在Python中,我定义了一个类:
class X():
_CON = 0
def __init__(self, var):
self.y = var*self._CON
是否可以为_CON
的实例更改常量X
?例如,我尝试执行以下操作
X._CON = 3
x = X(2)
a = x.y
我希望_CON
从0更改为3,因此self.y = var*_CON = 2*3 = 6
。没有创建新课程的正确方法是什么?
修改:
我找到了答案。我的第二个代码有效。但是,它不会更改类_CON
的实例x
的{{1}},而是更改类X
本身的实例X
。以下代码更改了实例_CON
的{{1}}而不是类x
的更改。
X
答案 0 :(得分:1)
_CON
是类级变量,而不是实例级变量。如果您在课程中更改_CON
,那么{X}的所有实例的_CON
值都会发生变化。如果_CON
的值不是静态的,那么我会包括它作为实例级变量,而不是将其定义为类变量。
答案 1 :(得分:1)
实际上是。分配给实例属性时,将屏蔽类属性。
因此,如果您执行C()._CON
,那么您将引用实例命名空间,而如果您执行C._CON
则指的是类命名空间。您可以指定实例和类属性未被触及。
c = C()
c._CON = random()
您可以通过self.__class__._CON
或type(self)._CON
这些都没有经过测试。
请注意_CON
未X.__init__
未全局定义,因此您应该在NameError: global name _CON is not defined
行收到x = X(2)
错误。
还有另一个问题,因为您在_CON
中使用__init__
,在实例化后更改它将对y
属性没有影响,因为此值已经计算过。在这种情况下,最好的做法是扩展X
类并自定义_CON
属性。
class Y(X):
_CON = 3
y = Y(2)
答案 2 :(得分:1)
正如我在this comment中所说的,我将在此处进行扩展,如果OP希望能够动态更改X._CON
,即使在实例化x = X(var)
之后并且没有编写新的然后,一种方法可能是y
property和var
这样的实例属性:
class X(object):
_CON = 0
def __init__(self, var):
self.var = var
@property
def y(self):
return self.var * X._CON
然后......
>>> x = X(2)
>>> x.y # returns 0
>>> X._CON = 3
>>> x.y # returns 6
N.B。:正如其他人已经指出并且我认为OP已经发现,此示例使用类属性X._CON
,对类属性的更改将影响该类的所有实例。例如,在从上面实例化x = X(var)
后执行以下操作,X._CON
的值仍为3;它不会是0。
请注意以下示例中资本X
类与实例之间的差异:
x
因此,如果您希望>>> x._CON = 23 # <-- doesn't affect x.y b/c x.y = x.var * X._CON
>>> x.y # still returns 6 b/c X._CON = 3 still
>>> x10 = X(10)
>>> x10.y # returns 30 b/c X._CON = 3
>>> x._CON # returns 23
>>> x10._CON # returns 3 since we changed X._CON to 3
>>> X._CON # returns 3 <-- this is the **class** attribute
的值特定于每个实例,请使用_CON
代替self._CON
。重新开始...
X._CON
然后......
class X(object):
_CON = 0
def __init__(self, var):
self.var = var
@property
def y(self):
return self.var * self._CON # <-- use **instance** attribute
还有一些变体,例如,如果您更改类属性>>> x = X(2)
>>> x.y # returns 0
>>> x._CON = 3 # <-- use **instance** attribute
>>> x.y # returns 6
>>> x10 = X(10)
>>> x10.y # returns 0 b/c x10._CON = X._CON = 0
>>> x10._CON = 7 # <-- use **instance** attribute
>>> x10.y # returns 70
>>> x._CON # returns 3
>>> x10._CON # returns 7
>>> X._CON # returns 0
,则使用x._CON
的第二个示例中的实例属性x10._CON
和self._CON
会发生什么变化在设置实例属性X._CON
或x._CON
之前或之后。我将留下这些例子供读者探讨。
答案 3 :(得分:0)
是否可以更改X实例的常量_CON。
不。如果需要,您必须使用self.con
等实例变量。
在您的示例中,_CON
附加到班级X
。要将其附加到实例,必须使用self
。
答案 4 :(得分:-1)
不,从实例/对象中无法更新类变量。因为它是设计的,所有对象必须是恒定的。虽然存在一些技巧(创建一个更新变量的类方法,或者像往常一样使用 init 方法。)..
class MyClass:
_CON = 1
@classmethod
def update(cls, value):
cls._CON += value
def __init__(self,value):
self.value = value
self.update(value)
a = MyClass(1)
print (MyClass._CON) #o/p: 2
在你更新任何以下划线开头的东西之前你必须先思考10次(有人说不要碰它......)