Python—如何将实例变量作为隐式参数和递归方法传递给方法

Python—如何将实例变量作为隐式参数和递归方法传递给方法,python,regex,python-3.x,Python,Regex,Python 3.x,我在将对象的实例变量传递给实例方法时遇到了一个问题 我已经在别处搜索过了,但我一直在寻找关于如何使用self将对象传递给方法的信息,我已经知道了,或者只是关于类和实例方法之间的一般差异的教程,它们没有具体回答我的问题。我的问题的答案肯定存在于某个地方,我想我只是不知道该问什么 在我的代码中,我有这样一个类: class SongData: def __init__(self, datapoint): self.artist = datapoint['artist']

我在将对象的实例变量传递给实例方法时遇到了一个问题

我已经在别处搜索过了,但我一直在寻找关于如何使用
self
将对象传递给方法的信息,我已经知道了,或者只是关于类和实例方法之间的一般差异的教程,它们没有具体回答我的问题。我的问题的答案肯定存在于某个地方,我想我只是不知道该问什么

在我的代码中,我有这样一个类:

class SongData:

    def __init__(self, datapoint):
        self.artist = datapoint['artist']
        self.track = datapoint['name']

    def xtradata_rm(self, regex, string=None):
        if string is None:
            string = self
        srchrslts = re.search(regex, string)
        if srchrslts is not None:
            if regex == 'f.*?t':
                self = self.replace(string,'')
                self.xtradata_rm('\((.*?)\)')
            else:
                self.xtradata_rm('f.*?t', srchrslts)

    def example_method(self):
        #This one isn't actually in the code, included for ease of explanation.
        print(self) 

    #some more methods irrelevant to question down here.
假设我们通过执行
song=SongData(datapoint)
来实例化一个对象。方法
xtradata_rm
应该搜索
song.artist
song.track
字符串中括号中的某个部分,然后如果找到的部分包含任何形式的单词“featured”,请将其从字符串中删除,然后重试,直到括号中没有包含“featured”的表达式为止找到了

我现在意识到这可能是对自我的100%的错误使用,但我不知道应该用什么来代替它来实现我想要的行为。因此,在我的脚本中,我尝试:

file_list = glob.glob("*procData.json")


for datafname in file_list:
    datafile = json.load(open(datafname))

    for i, datapoint in enumerate(datafile['EnvDict']):
        song = SongData(datapoint)
        song.track.xtradata_rm('\((.*?)\)')
        song.releasefetch(lfmapi)
        song.dcsearcher(dcapi)
        datapoint.update({"album": song.release, "year": song.year})

    with open("upd" + datafname, 'w') as output:
        json.dump(datafile, output)
但是我得到了这个错误:

Traceback (most recent call last):
    song.track.xtradata_rm('\((.*?)\)')
AttributeError: 'str' object has no attribute 'xtradata_rm'
如果我注释掉那一行,代码就会运行

因此,我的第一个问题是,一般来说,我必须做什么才能转到
song.track.example\u method()
song.artist.example\u method()
,并在控制台中按预期分别打印
track\u name
artist\u name

我的第二个问题是,如何使用
xtradata_rm
(即。
能够执行
song.track.xtradata_rm('\(.*)\)
并在方法中插入
song.track
以代替
self
),以及
xtradata_rm
递归并尝试将实例变量隐式传递给自身如何改变事情

看起来您想将方法
xtradata\u rm
添加到
str
对象
self.artist
self.track

关于Python,您误解的一点是,不能通过为变量
self
(或任何其他变量)赋值来更改对象
self=123
不会将名称
self
后面的对象更改为
123
,它使名称
self
指向对象
123
(并且只在当前范围内执行)

要真正做到这一点,你应该看Ned Batchelder的演讲

另一件事是
str
对象是不可变的,因此即使名称按预期工作,也无法修改
str
。例如,
bytearray
是可变的,
str
不是可变的,请参见区别:

In [1]: b = bytearray(b'My example string')

In [2]: id(b)
Out[2]: 4584776792

In [3]: b[3:10] = b'modified'

In [4]: b
Out[4]: bytearray(b'My modified string')

In [5]: id(b) # same object
Out[5]: 4584776792

In [6]: s = 'My example string'

In [7]: s[3:10] = 'modified'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-22fe89ae82a3> in <module>()
----> 1 s[3:10] = 'modified'

TypeError: 'str' object does not support item assignment

In [8]: new_s = s.replace('example', 'modified')

In [9]: id(new_s) # different object
Out[9]: 4584725936

In [10]: id(s)
Out[10]: 4584762296

In [11]: s # original string unmodified
Out[11]: 'My example string'
输出:

My Song Name <class '__main__.SongAttribute'>
MY SONG NAME <class '__main__.SongAttribute'>

My_Song_Name <class '__main__.SongAttribute'>

My Song Name <class '__main__.SongAttribute'>
My_Song_Name <class '__main__.SongAttribute'>
My_Song_Name <class '__main__.SongAttribute'>

代码的问题是您试图将
song.track
作为
self
传递到
xtradata\u rm
方法。相反,当您将
xtradata\u rm
方法作为
song.xtradata\u rm('\(.*)\)
调用时,请在
xtradata\u rm
方法中使用self.track
My Song Name <class '__main__.SongAttribute'>
MY SONG NAME <class '__main__.SongAttribute'>

My_Song_Name <class '__main__.SongAttribute'>

My Song Name <class '__main__.SongAttribute'>
My_Song_Name <class '__main__.SongAttribute'>
My_Song_Name <class '__main__.SongAttribute'>
def __init__(self, datapoint):
    self.artist = SongAttribute(datapoint['artist'])
    self.track = SongAttribute(datapoint['name'])