python classmethod是否可以更改实例变量的值,反之亦然?

时间:2019-07-11 20:49:38

标签: python

python classmethod可以更改实例变量的值吗?

普通方法可以更改类变量的值吗?

3 个答案:

答案 0 :(得分:1)

否,是。

类方法无法访问实例对象。

尽管实例方法可以通过self.__class__访问类对象。

但是,在实例方法中更改类的全局值是一个坏主意,因为这是意外的副作用。

可以通过self透明地访问类级属性,就像实例特定的属性一样。因此,如果您需要为特定实例覆盖类级属性,只需在self中分配它即可:

In [1]: class C(object):
   ...:     ca=1
   ...:     cb=1
   ...:     def inc_ca(self):
   ...:         self.ca+=1
   ...:

In [2]: c=C()

In [4]: c.ca
Out[4]: 1

In [5]: c.ca=2

In [6]: c.ca
Out[6]: 2

In [7]: c.inc_ca()

In [8]: c.ca
Out[8]: 3

In [9]: C.ca
Out[9]: 1

答案 1 :(得分:1)

  

python classmethod可以更改实例变量的值吗?

不。类对象没有对任何实例变量的直接访问。

  

常规方法可以更改类变量的值吗?

是;但更改将在其自己的视图上进行(除非名称通过使用类显式引用,例如 by name self.__class__ ),即不会更改由类或任何其他对象看到的类变量。如果明确引用了类对象,则您将可以想象地更改了类变量。

答案 2 :(得分:1)

python中的任何函数都可以更改其有权访问的任何变量。


但这是一个广泛的答案。让我们依次检查您的两个问题:

  

类方法可以更改实例变量的值吗?

请考虑以下课程:

class A:
    def __init__(self):
        self.prop1 = 2
        self.prop2 = "Beaver"

    @classmethod
    def do_something(cls):
        ...

如果我们位于do_something内,则不知道是否存在任何特定实例。如果您要通过参数将A的实例传递给方法,那么我们可以对该实例做任何我们想做的事情,但是除非A的实例存储在我们可以看到的地方,否则您可以不要从内部进行修改。

一种解决方法是在类变量中保留实例列表:

class A2:
    instances = []

    def __init__(self):
        # setting instance variables
        self.prop1 = 2
        self.prop2 = "Beaver"
        # setting class variables
        A2.instances.append(self)

    @classmethod
    def do_something(cls):
        ...

这一次,我们将能够从do_something内部访问实例,因为该实例将位于instances中的某个类变量。

  

实例方法可以更改类变量的值吗?

是的,因为任何实例方法都必须有权访问实例的类。您可以像上面在类A2中所做的那样显式地编写此代码,或者如果您正在处理多态性,则可以访问实例的__class__属性:

class B(A2):
    def __init__():
        self.prop1 = 7
        self.prop2 = "Chihuaua"
        self.__class__.instances.append(self)

“您可以更改任何可以看到的内容”的原则很有趣,而且很危险。例如,您可以重新定义内置方法,甚至可以从其外部更改类方法(在这里,我将在类本身之外重新定义类__init__()的{​​{1}}方法B的所有新实例将使用我的构造函数,而不是最初随附的B的构造函数):

B

除非您确切知道自己在做什么,否则走下这个兔子洞是极其危险的。