- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
从Programming Language Pragmatics by Scott,
图3.14 Python中的深度绑定。右侧是运行时堆栈的概念图。
封闭中捕获的引用环境显示为虚线框和箭头。什么时候
通过形式参数P调用B,存在两个I实例。因为P的闭包是
在A的初始调用中创建的B的静态链接(实心箭头)指向该A的框架
调用。 B在其print语句中使用该调用的I实例,并且输出为1。
问题在于,正在运行的程序可能具有一个以上在递归子例程中声明的对象的实例。一种语言的闭包
静态作用域在关闭时捕获每个对象的当前实例
被建造。调用闭包的子例程时,即使随后通过递归调用创建了新的实例,它也会找到这些捕获的实例。
因此,基本上,引号试图解释以下程序(与屏幕快照中的程序相同)打印出1
:
def A(I, P):
def B():
print(I)
# body of A:
if I > 1:
P()
else:
A(2, B)
def C():
pass # do nothing
A(1, C) # main program
2
而不是
1
:
def A(I, P):
def B():
print(I)
if I > 2:
P()
elif I > 1:
A(3, B)
else:
A(2, B)
def C():
pass
A(1, C)
1
:
def A(I, P):
def B():
print(I)
if I > 2:
P()
elif I > 1:
A(3, P)
else:
A(2, B)
def C():
pass
A(1, C)
最佳答案
评论已经太久了,因此我将其添加为答案。
我应该说,我是从一个了解其他语言的人的角度回答这个问题的:我现在主要写Python,但是我的术语可能是“错的”(对于它来说,它读的是“正确的,但是后来的语言却像Python弄错了......)。特别是,我故意滑过一堆特定于Python的细节,并避免处理诸如绑定的可变性和Python 3 nonlocal
hack之类的事情。
我还认为本书对“深层装订”一词的用法令人困惑,甚至可能是错误的:请参阅结尾处的注释。因此,我在很大程度上忽略了它。
绑定,范围和程度
有三个重要概念。
绑定是名称与其表示的内容之间的关联。最常见的绑定类型是将变量名称与值相关联的变量绑定:还有其他种类(例如,异常类与处理程序之间的绑定,它们由try: ... except: ...
构造方法建立),但我只讲变量绑定。
绑定的范围是可访问的代码区域。
绑定的程度是可访问的时间。
范围和范围有几种选择。对于变量绑定,Python具有:
词法作用域,这意味着绑定只能由在源代码中可见的代码访问;
和无限的范围,这意味着只要有可能进行引用就存在绑定。
(另一个常见的范围是动态的:具有动态范围的绑定对于在源代码中可见的任何代码以及从该代码“向下”堆栈的任何代码均可见。另一个常见的范围是确定的,这意味着当控制离开建立它的构造时,绑定就会消失。例如,异常处理程序的绑定在Python中具有动态范围和确定的范围。)
词法作用域的意思是,您(几乎)可以通过阅读源代码来了解一点代码所指的绑定。
所以考虑一下:
def outer():
a = 2
def inner(b):
return a + b
return inner(2)
a
绑定在
outer
中,而
b
绑定在
inner
中(实际上,有三个绑定:
inner
也绑定到了
outer
中的函数)。这两个绑定中的每个绑定均被引用一次:在
inner
中(而
inner
绑定在
outer
中被引用一次)。
a
中对
inner
的引用是什么:对
outer
中建立的绑定。这就是“词法”的意思:您(和编译器,如果足够聪明的话)可以通过查看源代码来知道存在哪些绑定。
def maybe(x):
return x + y
maybe
中创建了一个绑定,但是有两个引用:
y
是对不存在的绑定的引用。但是它可能存在:可能存在
y
的顶级绑定,这会使此代码起作用。因此,围绕词法绑定有一个特别的警告:存在一个“顶层”环境,所有定义都可以“看到”并且其中可以包含绑定。因此,如果上面的片段被放大以读取
y = 4
def maybe(x):
return x + y
maybe
可以“看到”顶级环境(实际上,在Python中,这是定义它的模块中的绑定)。
def outer(x):
def inner(y):
return x + y
return inner
outer
绑定
x
和
inner
,并且
inner
绑定
y
(并且可以看到
x
和
inner
)。因此,现在让
add4 = outer(4)
:
add4(3)
应该返回什么(或者等效地,
outer(4)(3)
应该返回什么)?好吧,答案是
7
。之所以如此,是因为
x
的绑定存在的时间就可以被引用,或者换句话说,由于
inner
的任何实例存在,它都存在,因为它们引用了它。这就是“无限范围”的意思。
outer(4)(3)
将是某种错误,因为它会引用不再存在的绑定。仅具有确定的范围的语言实际上无法以任何有用的方式具有一流的功能。)
def adder(n):
return lambda e: e + n
a1 = adder(12)
a2 = adder(15)
a1
和
a2
引用
n
的不同绑定:
a1(0)
是
12
,而
a2(0)
是
15
。因此,通过阅读源代码,您可以知道捕获了哪些绑定,但是您需要运行它来了解捕获了哪些绑定-换句话说,变量的值是多少。
def signaller(initial):
s = [initial]
def setter(new):
s[0] = new
return new
def getter():
return s[0]
return (setter, getter)
(str, gtr) = signaller(0)
str
和
gtr
捕获了
s
的相同绑定,因此
str(1)
将导致
gtr()
返回
1
。
def A(I, P):
def B():
print(I)
# body of A:
if I > 1:
P()
else:
A(2, B)
def C():
pass # do nothing
A(1, C) # main program
A
时,有一个本地函数
B
可以看到
I
的绑定(还有
P
和
B
本身,但它没有引用这些绑定,因此可以忽略)他们)。每次对
A
的调用都会为
I
,
P
和
B
创建新的绑定,并且这些绑定对于每个调用都是不同的。这包括递归调用,这是在这里使您感到困惑的技巧。
A(1, C)
是做什么的?
I
绑定到
1
,并将
B
绑定到一个可以看到
I
绑定的闭包。它还将
P
绑定到
C
的全局(模块)值,该值是一个函数,但没有任何内容引用此绑定。
I
的参数和
1
的值(刚创建的闭包)递归调用自身(因为
2
是
B
)。
I
现在绑定到
2
,并且
P
绑定到外部调用的闭包。
B
。没有任何内容涉及此绑定。
P
的闭包。它是在外部调用中创建的闭包,对于
I
可以看到的绑定是对其可见的绑定,其值为
1
。这样它打印
1
,我们就完成了。
from __future__ import print_function # Python 2
def A(I, P):
def B():
print(I)
print("{I} {P} {B}".format(I=I, P=P, B=B))
if I > 1:
P()
else:
A(2, B)
def C():
pass
A(1, C)
1 <function C at 0x7f7a03768e60> <function B at 0x7f7a03768d70>
recursing with (2, <function B at 0x7f7a03768d70>)
2 <function B at 0x7f7a03768d70> <function B at 0x7f7a03651a28>
calling <function B at 0x7f7a03768d70>
1
B
的函数:其中一个与在外部调用中创建的函数相同(将被调用),而另一个是刚刚创建的函数闭包,将不再引用。
关于python - 我将如何理解Python中的这个深度绑定(bind)示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45872572/
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Sample data for IPv6? 除了 wireshark 在其网站上提供的内容之外,是否有可以下
我正在寻找可以集成到现有应用程序中并使用多拖放功能的示例或任何现成的解决方案。我在互联网上找到的大多数解决方案在将多个项目从 ListBox 等控件拖放到另一个 ListBox 时效果不佳。谁能指出我
我是 GATE Embedded 的新手,我尝试了简单的示例并得到了 NoClassDefFoundError。首先我会解释我尝试了什么 在 D:\project\gate-7.0 中下载并提取 Ga
是否有像 Eclipse 中的 SWT 示例那样的多合一 JFace 控件示例?搜索(在 stackoverflow.com 上使用谷歌搜索和搜索)对我没有帮助。 如果它是一个独立的应用程序或 ecl
我找不到任何可以清楚地解释如何通过 .net API(特别是 c#)使用谷歌计算引擎的内容。有没有人可以指点我什么? 附言我知道 API 引用 ( https://developers.google.
最近在做公司的一个项目时,客户需要我们定时获取他们矩阵系统的数据。在与客户进行对接时,提到他们的接口使用的目前不常用的BASIC 认证。天呢,它好不安全,容易被不法人监听,咋还在使用呀。但是没办法呀,
最近在做公司的一个项目时,客户需要我们定时获取他们矩阵系统的数据。在与客户进行对接时,提到他们的接口使用的目前不常用的BASIC 认证。天呢,它好不安全,容易被不法人监听,咋还在使用呀。但是没办法呀,
我正在尝试为我的应用程序设计配置文件格式并选择了 YAML。但是,这(显然)意味着我需要能够定义、解析和验证正确的 YAML 语法! 在配置文件中,必须有一个名为 widgets 的集合/序列。 .这
你能给我一个使用 pysmb 库连接到一些 samba 服务器的例子吗?我读过有类 smb.SMBConnection.SMBConnection(用户名、密码、my_name、remote_name
linux服务器默认通过22端口用ssh协议登录,这种不安全。今天想做限制,即允许部分来源ip连接服务器。 案例目标:通过iptables规则限制对linux服务器的登录。 处理方法:编
我一直在寻找任何 PostProjectAnalysisTask 工作代码示例,但没有看。 This页面指出 HipChat plugin使用这个钩子(Hook),但在我看来它仍然使用遗留的 Po
我发现了 GWT 的 CustomScrollPanel 以及如何自定义滚动条,但我找不到任何示例或如何设置它。是否有任何示例显示正在使用的自定义滚动条? 最佳答案 这是自定义 native 滚动条的
我正在尝试开发一个 Backbone Marionette 应用程序,我需要知道如何以最佳方式执行 CRUD(创建、读取、更新和销毁)操作。我找不到任何解释这一点的资源(仅适用于 Backbone)。
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题?通过 editing this post 添加详细信息并澄清问题. 去年关闭。 Improve this
我需要一个提交多个单独请求的 django 表单,如果没有大量定制,我找不到如何做到这一点的示例。即,假设有一个汽车维修店使用的表格。该表格将列出商店能够进行的所有可能的维修,并且用户将选择他们想要进
我有一个 Multi-Tenancy 应用程序。然而,这个相同的应用程序有 liquibase。我需要在我的所有数据源中运行 liquibase,但是我不能使用这个 Bean。 我的应用程序.yml
我了解有关单元测试的一般思想,并已在系统中发生复杂交互的场景中使用它,但我仍然对所有这些原则结合在一起有疑问。 我们被警告不要测试框架或数据库。好的 UI 设计不适合非人工测试。 MVC 框架不包括一
我正在使用 docjure并且它的 select-columns 函数需要一个列映射。我想获取所有列而无需手动指定。 如何将以下内容生成为惰性无限向量序列 [:A :B :C :D :E ... :A
$condition使用说明和 $param在 findByAttributes在 Yii 在大多数情况下,这就是我使用 findByAttributes 的方式 Person::model()->f
我在 Ubuntu 11.10 上安装了 qtcreator sudo apt-get install qtcreator 安装的版本有:QT Creator 2.2.1、QT 4.7.3 当我启动
我是一名优秀的程序员,十分优秀!