学习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
谁能告诉我这为什么可行以及它有什么好处?如果我可以从外部更改类中的关键值,那么与将类定义为蓝图并不矛盾,这是否与OOP
的{{1}}范例冲突。来自encapsulation
的我实际上只是知道通过getter和setter访问变量,而不仅仅是这样。所以我很好奇这是允许的重要目的。
答案 0 :(得分:1)
为什么有可能? Python没有遵循严格的编程范式,这意味着如果在某些情况下有意义的话,解释器就不会妨碍程序员愿意这样做。
话虽这么说,但是这种方法需要程序员方面更高的纪律和责任感,而且还允许其元编程功能具有更大程度的灵活性。
因此,最后这是一个设计选择。这样做的好处是您不需要显式地使用getter / setter。
对于受保护的/私人的成员/方法,习惯上分别在_
或__
之前加上前缀。此外,通过方法装饰器@property
和@.setter
,可以伪造一个受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:无法设置属性
当然您仍然可以这样做:
x._an_attribute = 2
x.an_attribute
# 2
( EDIT:添加了更多代码以更好地显示用法)
此外,在您的代码中,您还需要在定义该类之后修改该类,并且所做的更改具有追溯(某种)效果。 这通常称为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
但是,如果有更简洁的选择,那么这当然不是鼓励的编程风格。