为什么 class 变量可以从外部访问

Why is a class variable accessable from outside

学习中Python 刚刚遇到一些不太懂的东西。让我们举个例子:

class CV_Test:
    classVar = 'First'

cv = CV_Test()
print(cv.classVar)
CV_Test.classVar = 'Second'
cv2 = CV_Test()
print(cv2.classVar)
print(CV_Test.classVar)

输出:

First
Second
Second

谁能告诉我为什么这是可能的,它有什么好处?如果我可以从外部更改 class 中的关键值,这是否与将 class 定义为蓝图相矛盾,这是否与 [=14] 的 OOP 范式冲突=].来自 .NET 我实际上只知道通过 getter 和 setter 访问变量但不只是这样。所以我很好奇允许这样做的重要目的是什么。

为什么可能? Python 不遵循限制性编程范式,这意味着如果某件事在某些情况下有意义,解释器不应妨碍程序员愿意这样做。

话虽这么说,这种方法要求程序员方面有更高水平的纪律和责任,但也允许其元编程功能具有更大程度的灵活性。

所以,这最终是一种设计选择。它的优点是你不需要明确地必须使用 getters/setters.

对于protected/private members/methods,习惯上分别加上___。此外,可以通过方法装饰器 @property 和 [=19] 伪造 getter/setter 受保护的行为(这也将允许执行其他代码) =],例如:

class MyClass():
    _an_attribute = False

    @property
    def an_attribute(self):
        return self._an_attribute

    @an_attribute.setter
    def an_attribute(self, value):
        self._an_attribute = value

可以这样使用:

x = MyClass()

x.an_attribute
# False

x.an_attribute = 1
# sets the internal `_an_attribute` to 1.

x.an_attribute
# 1

你可以省略 @an_attribute.setter 部分,如果你想要 只读 (有点)属性,那么下面的代码:

x = MyClass()

x.an_attribute
# False

但是,尝试更改其值会导致:

x.an_attribute = 1

AttributeError: can't set attribute

当然你还可以:

x._an_attribute = 2

x.an_attribute
# 2

(编辑:添加了更多代码以更好地显示用法)

编辑:关于猴子补丁

此外,在您的代码中,您还修改了 class 的定义,并且这些更改具有追溯(某种)效果。 这通常称为 monkey patching 并且在某些情况下再次有用,您希望在代码的某些部分触发特定行为同时保留其大部分逻辑,例如:

class Number():
    value = '0'

    def numerify(self):
        return float(self.value)

x = Number()
x.numerify()
# 0.0

Number.numerify = lambda self: int(self.value)
x.numerify()
# 0

但如果有更简洁的选项可用,这肯定不是一种鼓励的编程风格。