为什么允许使用这段代码,使用它是一种好习惯吗?我有很多 Java 经验,这使得在 Python 中初始化变量看起来非常不正式。
class MyClass(object):
def __init__(object):
pass #no mention of x here
def setX(self,x):
self.x = x #why is this allowed
def getX(self):
return self.x
Run Code Online (Sandbox Code Playgroud)
问题“为什么允许这样做?” 通过最好回答“为什么会不会允许?” 通常,任何 Python 对象都可以在任何时候为其分配任何名称的属性。与 Java 等语言需要在编译时知道对象的完整内存布局不同,Python 中的对象属性存储在字典中。字典可以保存任意数量的项目,因此没有什么可以阻止您在任何时候分配任何属性。__init__()它的特殊之处在于它在实例化时执行,但它绝不定义对象允许的属性名称集。
有一种方法可以防止随意分配属性,那就是使用__slots__属性。然而,这主要是为了内存优化;无法添加任意属性是一个副作用。它仍然不会阻止您在外部初始化属性__init__():
class MyClass(object):
__slots__ = ("x",) # x is the only attribute allowed
def setX(self,x):
self.x = x
def getX(self):
return self.x
Run Code Online (Sandbox Code Playgroud)
您还可以编写一个自定义__setattr__方法来过滤掉您不想允许的属性,但这很容易绕过,并且通常与 Python 的“我们都是成年人”的哲学相悖。
拥有依赖于实例化时不可用的状态的方法是一种糟糕的编程实践,但您似乎理解这一点。