类中的字段变量 (Python)

use*_*285 3 python object

为什么允许使用这段代码,使用它是一种好习惯吗?我有很多 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)

kin*_*all 5

问题“为什么允许这样做?” 通过最好回答“为什么会不会允许?” 通常,任何 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 的“我们都是成年人”的哲学相悖。

拥有依赖于实例化时不可用的状态的方法是一种糟糕的编程实践,但您似乎理解这一点。