我有以下 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
我的问题是这样的;
从 myClass
中打印 myVar
的内容和/或从 init
重新分配它们的正确方法是什么?
最佳答案
您面临的问题是因为您不了解类声明的作用域是如何工作的。类声明在其自己的范围内执行。执行完成后,会创建一个新的类对象,并将获得的作用域作为其 __dict__
附加到该类。
注意:类范围不能从方法范围内搜索!这意味着当在方法定义中时,您必须将类属性引用为MyClass.attribute
。
例如:
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)
注意:由于在执行其声明时该类已不存在,因此您不能在 MyClass
的“顶层”引用 MyClass
> 声明:
class MyClass:
var = 1
print(MyClass.var) # error: MyClass still doesn't exist.
<小时/>
这样做的副作用是以下代码:
class MyClass:
x = 1
results = list(i+x for i in range(10))
产品:
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
因为事实上,生成器表达式(以及 python3 中的列表推导式)被视为具有自己作用域的函数。由于未从内部函数作用域中搜索类作用域,因此无法找到 x
。
您可以使用函数定义和默认值来解决这个问题:
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)))()
这通常不是问题,因为类定义很少包含除方法定义和一些常量之外的任何内容。
<小时/>已经有一些关于类范围的问题:
关于python - 如何在 Python 中的类中引用静态属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24505869/