python:绑定如何工作
我想了解 python 中的变量绑定到底是如何工作的。让我们看看这个:
def foo(x):
def bar():
print y
return bar
y = 5
bar = foo(2)
bar()
这打印了 5,这对我来说似乎是合理的。
def foo(x):
def bar():
print x
return bar
x = 5
bar = foo(2)
bar()
这会打印 2,这很奇怪。在第一个示例中,python 在执行期间查找变量,在第二个示例中,则在创建方法时查找变量。为什么会这样呢?
需要明确的是:这非常酷并且完全按照我的意愿工作。但是,我对内部 bar 函数如何获取其上下文感到困惑。我想了解幕后发生了什么。
编辑
我知道,局部变量具有更高的优先级。我很好奇,python 如何知道在执行过程中从我之前调用过的函数中获取参数。 bar
是在 foo
中创建的,而 x
已不存在。创建函数时是否已将此 x 绑定到参数值?
I am trying to understand, how exactly variable binding in python works. Let's look at this:
def foo(x):
def bar():
print y
return bar
y = 5
bar = foo(2)
bar()
This prints 5 which seems reasonable to me.
def foo(x):
def bar():
print x
return bar
x = 5
bar = foo(2)
bar()
This prints 2, which is strange. In the first example python looks for the variable during execution, in the second when the method is created. Why is it so?
To be clear: this is very cool and works exactly as I would like it to. However, I am confused about how internal bar function gets its context. I would like to understand, what happens under the hood.
EDIT
I know, that local variables have greater priority. I am curious, how python knows during execution to take the argument from a function I have called previously. bar
was created in foo
and x
is not existing any more. It have bound this x
to the argument value when function was created?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是作用域的问题,第二个示例使用局部作用域变量 x,即上面全局声明的变量
It is mater of scope, second example uses local scope variable x, that is preceded above globally declared
在这两个示例中,查找都在运行时发生。唯一的区别是有一个本地定义的变量
x
,而没有本地定义的变量y
。当执行……时
,
print
语句查找名为y
的变量,并且只在全局上下文中找到它,因此它使用该变量,并打印“ 5”。在......
当查找发生时,定义了一个作用域变量
x
——当foo
时,它被固定为“5” code> 函数被调用。关键是参数在传递给函数时进行求值,因此外部函数 foo 会在调用时对传入的参数进行求值。这实际上在
foo
函数的上下文中创建了一个名为x
的变量,因此每当bar
执行时,它都会看到该变量,而不是全局定义的变量一。这有时会令人困惑,如以下代码所示:
您需要执行以下操作:
In both examples, the lookup happens at runtime. The only difference is that there's a locally defined variable
x
, while there isn't a locally defined variabley
.When executing ...
... the
print
statement looks up the variable namedy
, and only finds it in the global context, so it uses that one, and prints "5".In ...
... when the lookup occurs, there is a scoped variable
x
defined--which is fixed at "5" when thefoo
function is called.The key is that arguments are evaluated at the time they're passed into functions, so the outer function
foo
evaluates the arguments passed in when it's called. This effectively creates a variable calledx
in the context of thefoo
function, so wheneverbar
executes it sees that variable, and not the globally defined one.This can occasionally be confusing, as in the following code:
You need to do:
没什么奇怪的,这是因为函数参数中的“x”比全局变量“x”具有更高的优先级。
首先,全局变量是一个大祸害。
Python 有“global”运算符:
Nothing strange, it is because "x" from function argument has higher priority than global variable "x".
At first, global variables is a great evil.
Python has operator "global":
第二个示例实现了所谓的闭包。函数
bar
从其周围上下文(即函数foo
)引用变量x
。这先于对全局变量 x 的引用。另请参阅这个问题 你能解释一下闭包吗(因为它们与 Python 相关) )?
The second example implements what is called a closure. The function
bar
is referencing the variablex
from its surrounding context, i.e. the functionfoo
. This precedes the reference to the global variablex
.See also this question Can you explain closures (as they relate to Python)?
您提到的问题是 python 中变量的词法作用域与动态作用域之一。明确地说,Python 定义了以下四个作用域。
在第一个示例中,其中“y”在函数栏之外定义,python 搜索最内层作用域并沿链向上移动,直到找到模块中的全局变量“y”
在第二个示例中,其中“x”由函数 foo(x) 定义,当 x 被打印在 bar 内时,x 属于封闭函数的范围。纯粹来说,已经定义了闭包。
为了进一步研究 python 中的作用域,我发现了以下 文章读得很好
The issue that you are alluding to is one of lexical vs dynamic scoping of variables in python. To be explicit, python defines the following four scopes.
In the first example, where "y" is defined outside of the function bar, python searched for the innermost scope and moved up the chain until it found the global variable "y" in the module
In the second example, where "x" is being defined by function foo(x), x belongs to the scope of an enclosing function, when its being printed inside bar. In pure terms, a closure has been defined.
For further study on scoping in python, I found the following article a great read