为什么 Python 类定义不能将闭包变量分配给自身?
为什么以下代码在 Python 中不起作用?
def make_class(a):
class A(object):
a=a
return A
Why doesn't the following work in Python?
def make_class(a):
class A(object):
a=a
return A
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
工作得很好:
顺便说一句,
function
不是 Python 中的保留关键字。works just fine:
btw,
function
is not a reserved keyword in Python.让我们用一个更简单的例子来解决同样的问题:
这会失败,因为 python 中的赋值没有附带
global
或nonlocal
语句,这意味着分配的名称是当前范围的本地名称。这种情况不仅发生在函数中,也发生在类定义中。这意味着您不能对全局变量和局部变量使用相同的名称并同时使用它们。您可以使用 Aaron Digulia 的答案中的解决方法,或使用不同的名称:
Let's use a simpler example for the same problem:
This fails because assignments in python, without an accompanying
global
ornonlocal
statement, means that the assigned name is local to the current scope. This happens not just in functions but also in class definitions.This means that you can't use the same name for a global and local variable and use them both. You can use the workaround from Aaron Digulia's answer, or use a different name:
两者似乎都工作正常(至少在 Python 2.5 中):
Both appear to work fine (in Python 2.5, at least):
尝试
您得到的错误(
NameError: name 'a' is not Defined
)是因为类中的名称a
遮盖了参数a
功能;因此,当您在代码中尝试“a=a”时,没有定义a
。换句话说,右侧a
不是来自def
的a
;相反,Python 在类A
中查找它,因为a
已经在赋值的左侧提到了。通过函数,这变得更加清晰:
显然,第一次打印应该打印 2,而不是 1,因此
a
的参数x
必须隐藏全局变量x.
b
是在x
被称为a
参数的范围内定义的,因此打印有效。但是,如果您尝试调用
c
,您会收到UnboundLocalError:赋值前引用的局部变量 'x'
,因为 Python 不会自动绑定全局变量。要解决此问题,您必须在赋值之前添加global x
。您的情况看起来更像是这样:
虽然在上面的示例中打印
x
有效,但赋值不起作用。这是确保变量不会泄漏的安全措施。解决方案是使用默认参数将变量“复制”到b
的作用域中:要解决您的问题,您需要告诉 Python“使参数
a
make_class
在A
中可见”,您需要在尝试分配类的字段a
之前执行此操作。这在 Python 中是不可能的。如果您可以使a
可见,则赋值将更改参数,而不是字段,因为 Python 无法区分这两者。由于您无法使其可见,因此没有可读取的
a
,因此出现NameError
。有关 Python 中名称范围的说明,请参阅此处。
Try
The error you get (
NameError: name 'a' is not defined
) is because the namea
in the class shadows the parametera
of the function; hence there is noa
defined when you try "a=a" in your code. In other words, the right sidea
is not thea
from thedef
; instead Python looks for it in the classA
sincea
was already mentioned on the left side of the assignment.This becomes more clean with functions:
Obviously, the first print should print 2, not 1, so the parameter
x
ofa
must shadow the global variablex
.b
is defined in a scope wherex
is known as a parameter ofa
, so the print works.If you try to call
c
, however, you getUnboundLocalError: local variable 'x' referenced before assignment
since Python doesn't bind global variables automatically. To fix this, you must addglobal x
before the assignment.Your case looks more like this:
While printing
x
worked in the example above, assignment doesn't work. This is a safety measure to make sure that variables don't leak. The solution is to use a default parameter to "copy" the variable intob
's scope:To solve your problem, you would need to tell Python "make the parameter
a
ofmake_class
visible inA
" and you would need to do that before you try to assign the fielda
of the class. This is not possible in Python. If you could makea
visible, the assignment would change the parameter, not the field, since Python has no way to distinguish the two.Since you can't make it visible, there is no
a
to read from, hence theNameError
.See here for an explanation of the scope of a name in Python.