python classmethod可以更改实例变量的值吗?
普通方法可以更改类变量的值吗?
答案 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
除非您确切知道自己在做什么,否则走下这个兔子洞是极其危险的。