假设我有以下Python代码:
import sys
class DogStr:
tricks = ''
def add_trick(self, trick):
self.tricks = trick
class DogList:
tricks = []
def add_trick(self, trick):
self.tricks.append(trick)
# Dealing with DogStr
d = DogStr()
e = DogStr()
d.add_trick('trick d')
e.add_trick('trick e')
print(d.tricks)
print(e.tricks)
# Dealing with DogList
d = DogList()
e = DogList()
d.add_trick('trick d')
e.add_trick('trick e')
print(d.tricks)
print(e.tricks)
使用Python 3.6.5运行此代码,我得到以下输出:
trick d
trick e
['trick d', 'trick e']
['trick d', 'trick e']
DogStr和DogList之间的区别在于我将tricks
视为前者的字符串,并将其视为后者的列表。
在处理DogStr时,技巧表现为实例变量。但是使用DogList技巧表现为类变量。
我希望在两个调用中看到相同的行为,即:如果输出的最后两行是相同的,那么应该是前两行。
所以我想知道。对此有何解释?
答案 0 :(得分:3)
区别在于对象的类型,而在于代码对它的作用。
这两者之间存在很大差异:
self.tricks = trick
和
self.tricks.append(trick)
第一个self.tricks = trick
为tricks
的{{1}}属性赋值。
第二个self
检索self.tricks.append(trick)
并在其上调用方法(此处修改其值)。
在您的情况下,问题是self.tricks
实例上没有定义tricks
,因此self
获取类的self.tricks.append
属性并对其进行修改,但是tricks
会在self.tricks = ...
上创建一个新属性。
其中一个是字符串而另一个是列表的事实并不真实。如果两者都是列表,那将是相同的。 请注意,它们不能都是字符串,因为字符串是不可变的,因此没有追加方法
这是错误的:
self
如果def add_trick(self, trick):
self.tricks = trick
是类属性,tricks
应该是类方法:
add_trick
如果@classmethod
def add_trick(cls, trick):
cls.tricks = trick
有理由成为实例方法,那么只需执行以下操作:
add_trick