[英]How to reference a static attribute from within a class in Python?
I have the following python snippet: 我有以下python片段:
class myClass:
myVar = 'a'
def __init__(self):
self.myOtherVar = 'b'
myVar = 'c' # Gets assigned but only as a local variable.
print myVar # prints 'a' !
print self.myOtherVar # says 'self' not found
My question is this; 我的问题是这个; What's the proper way to print the contents of
myVar
from within myClass
and/or re-assign them from init
? 从
myClass
打印myVar
的内容和/或从init
重新分配它们的正确方法是什么?
The problem you are facing is because you don't understand how the scoping of class declarations work. 您遇到的问题是因为您不了解类声明的范围如何工作。 A class declaration is executed in its own scope.
类声明在其自己的范围内执行 。 After the execution is completed a new class object is created and the obtained scope is attached to the class as its
__dict__
. 执行完成后,将创建一个新的类对象,并将获得的作用域作为
__dict__
附加到类中。
Note : the class scope is not searched from within the methods scopes! 注意 : 不在方法范围内搜索类范围! This means that you have to reference class attributes as
MyClass.attribute
when inside a method definition. 这意味着您必须在方法定义中引用类属性作为
MyClass.attribute
。
For example: 例如:
class MyClass:
var = 1
# we are executing this code as a single block
# so you must reference the variable as is usual
print(var)
# default values are *not* inside the definition.
# they are evaluated in the outer scope, so use plain "var" here
def method(self, a_default=var):
print(a_default)
def other_method(self):
# inside methods you are in a different scope
print(MyClass.var)
# equivalent *if* no "var" instance attributes exists
print(self.var)
Note: since the class doesn't still exist when executing its declaration you cannot refer to MyClass
at the "top level" of MyClass
declaration: 注:由于执行其声明中,您不能引用到上课的时候不依然存在
MyClass
在“顶级” MyClass
声明:
class MyClass:
var = 1
print(MyClass.var) # error: MyClass still doesn't exist.
A side effect of this, is that the following code: 这个的副作用是,以下代码:
class MyClass:
x = 1
results = list(i+x for i in range(10))
Produces: 生产:
NameError Traceback (most recent call last)
<ipython-input-6-f1d4417b2e52> in <module>()
----> 1 class MyClass:
2 x = 1
3 results = list(i+x for i in range(10))
4
<ipython-input-6-f1d4417b2e52> in MyClass()
1 class MyClass:
2 x = 1
----> 3 results = list(i+x for i in range(10))
4
<ipython-input-6-f1d4417b2e52> in <genexpr>(.0)
1 class MyClass:
2 x = 1
----> 3 results = list(i+x for i in range(10))
4
NameError: name 'x' is not defined
Because generator expressions (and list-comprehensions in python3) are, in fact, considered functions with their own scope. 因为生成器表达式(以及python3中的列表推导)实际上被认为是具有自己范围的函数。 Since the class scope isn't searched from inner function scopes the
x
cannot be found. 由于未从内部函数范围搜索类范围,因此无法找到
x
。
You can word around this using a function definition and default values: 您可以使用函数定义和默认值来解决此问题:
class MyClass:
x = 1
def _make_results(x=x):
return list(i+x for i in range(10))
results = _make_results()
del _make_results # otherwise it would be added as a method.
# or:
results = (lambda x=x: list(i+x for i in range(10)))()
This isn't usually a problem since class definitions rarely contain anything other than method definitions and a few constants. 这通常不是问题,因为类定义很少包含除方法定义和一些常量之外的任何内容。
There are already a few questions on SO about class scopes: 关于课程范围的问题已经有几个问题了:
self.var
will: self.var
将:
var
in self.__dict__
if present var
在self.__dict__
如果存在 var
in self.__class__.__dict__
if present var
在self.__class__.__dict__
如果存在 AttributeError
So use this or self.__class__.var
if you want to access the static variable minding inheritance . 因此,如果要访问静态变量minding继承,请使用this或
self.__class__.var
。 If you extend myClass
, the children instances will access the static variable in the child class. 如果扩展
myClass
,子实例将访问子类中的静态变量。
If you want to access the static variable in myClass
even when called from descendants, use myClass.var
. 如果要在
myClass
访问静态变量,即使从后代调用,也可以使用myClass.var
。
As for reassigning them, this must be done explicitly on the class object, or the assignment will just target the instance. 至于重新分配它们,必须在类对象上显式完成,或者赋值只是以实例为目标。
class myClass:
myVar = 'a'
def __init__(self):
self.myOtherVar = 'b'
print myVar # -> 'a'
class EmptyClass: pass
s = EmptyClass()
__init__(s)
myVar = s.myOtherVar
print myVar # -> 'b'
print myClass.myVar # -> 'b'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.