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'])