在Python中访问父类的静态变量
我有类似这样的代码
class A:
__a = 0
def __init__(self):
A.__a = A.__a + 1
def a(self):
return A.__a
class B(A):
def __init__(self):
# how can I access / modify A.__a here?
A.__a = A.__a + 1 # does not work
def a(self):
return A.__a
我能在类 B
中访问 __a
这个类变量吗?我可以用 a
来代替 __a
,这是不是唯一的方法?(我想答案可能很简单:是的 :)
3 个回答
1
在Python中,有两种装饰器,分别是@staticmethod
和@classmethod
,你可以用它们来声明一个方法是静态的或者与类相关的。这可以帮助你访问类中的数据元素:
class MyClass:
__a = 0
@staticmethod
def getA():
return MyClass.__a
class MyOtherClass:
def DoSomething(self):
print MyClass.getA() + 1
这个例子灵感来源于这个网站: http://www.rexx.com/~dkuhlman/python_101/python_101.html
3
这里提到的是 A._A__a
。在Python中,如果在一个类的定义里有以 __
开头的符号,这些符号会被自动加上 _<类名>
的前缀,这样做是为了让它们看起来有点像是“私有”的。也就是说,在 B
的定义中出现的 A.__a
,其实是指 A._B__a
,这可能让人感到意外。
>>> class Foo(object): _Bar__a = 42
...
>>> class Bar(object): a = Foo.__a
...
>>> Bar.a
42
11
所以,__a
不是一个 静态 变量,而是一个类变量。因为前面有两个下划线,所以它是一个 名称改名过的 变量。也就是说,为了让它看起来像是私有的,系统会自动把它改成 _<类名>__<变量名>
,而不是 __<变量名>
。这个变量仍然可以被 该类的实例 访问,使用 __<变量名>
的方式,但子类是不能享受这种特殊待遇的。
我建议你不要使用两个下划线,只用一个下划线来 (a) 表示它是私有的,以及 (b) 避免名称被改名。