我有以下名为MyClass的类:
def __init__(self, config):
self.response = Response(config)
self.utility = Utility()
self.listl = {}
它有以下方法:
def findSt(self, lv):
dvp = self.listl
if lv not in dvp:
raise Exception("ERROR: ....", lv)
else:
...
在我的主代码中,我使用同一个类的另一个方法(getvalues)为self.listl提供正确的值,即:
myobject = MyClass(config)
myobject.listl = myobject.getvalues()
lr = []
for lv in lvs:
lr.append(myobject.findSt(lv))
这有效,虽然我不确定这是否正确。我问的原因是因为如果我在主代码中执行以下拼写错误:
myobject.listL = myobject.getvalues()
没有错误提出!当然,在这种情况下myobject.listl
没有正确的运行时值,因此它不起作用,但为什么我可以创建一个不在__init__
的变量?
答案 0 :(得分:1)
出于同样的原因,您可以设置myobject.listl
- 您可以在任何地方设置任何实例的任何属性*,__init__
中设置的属性在任何方面都不是特殊的。关于__init__
唯一特别之处在于它是在创建新实例时自动调用的。
这并不意味着你必须使用它,通常最好不要在课外设置这些属性,我更喜欢有类似的方法
def setvalues(self):
self.listl = self.getvalues()
左右。一般来说,你需要小心,因为你有一个mutable属性,如果一些外部代码仍然拥有对旧self.listl的引用呢?然后该代码不会更改旧列表。这样就可以了:
def setvalues(self):
self.listl[:] = self.getvalues()
不重新设置listl属性,而只重新设置其中的值。但这是一个完全不同的讨论。
*:有一些例外,例如在C中实现的类,或者定义了__slots__
的类,但这些是罕见的例外。
答案 1 :(得分:1)
用户定义的类实例可以在运行时添加/删除属性:
>>> class A(object): pass
...
>>> a = A()
>>> a.something = 1 #no error. Now a has a new something attibute
>>>
虽然内置类型通常不允许这样做:
>>> a = object()
>>> a.something = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'something'
在python中,每个对象都有一个包含其属性的关联字典:__dict__
。这个字典是可变的。执行作业时:
instance.attribute = value
实际发生的是您要分配到对象的__dict__
:
instance.__dict__['attribute'] = value
事实上:
>>> class A(object):
... def __init__(self):
... self.something = 1
...
>>> a = A()
>>> a.__dict__
{'something': 1}
>>> a.other = 2
>>> a.__dict__
{'other': 2, 'something': 1}
>>> a.__dict__['other2'] = 3
>>> a.other2
3
在这方面, __init__
不特别。这只是一个约定,所有属性都在那里定义,但是当你将self.attribute = value
放在__init__
内时,你正在完全与上面相同的东西代码:创建新属性。
在大多数情况下进行初始化只是正确的方法。
类不(通常)声明其实例的一组预定义属性。一些元编程可以添加这种声明(例如,使用类装饰器/元类)。
如果您想提前定义班级的属性,可以使用__slots__
:
>>> class A(object):
... __slots__ = ('something',)
...
>>> a = A()
>>> a.something = 1
>>> a.other = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'other'
当您在类中定义__slots__
时,其实例不具有关联的__dict__
,因此无法在运行时添加属性
>>> a.__dict__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute '__dict__'
或者,您可以重新定义__setattr__
方法,以便更好地控制设置属性时发生的情况。