为什么Python中的函数可以打印封闭范围内的变量,但不能在赋值中使用它们? [复制]

2023-12-28

如果我运行以下代码:

x = 1

class Incr:
    print(x)
    x = x + 1
    print(x)

print(x)

它打印:

1
2
1

好吧,没问题,这正是我所期望的。如果我执行以下操作:

x = 1

class Incr:
    global x
    print(x)
    x = x + 1
    print(x)

print(x)

它打印:

1
2
2

也是我所期待的。那里没有问题。

现在,如果我开始创建一个增量函数,如下所示:

x = 1

def incr():
    print(x)

incr()

正如我所料,它打印了 1。我认为它这样做是因为它找不到x在其本地范围内,因此它搜索其封闭范围并找到x那里。到目前为止没有问题。

现在如果我这样做:

x = 1

def incr():
    print(x)
    x = x + 1

incr()

这在回溯中给了我以下错误:

UnboundLocalError:赋值前引用的局部变量“x”。

为什么 Python 不只是搜索封闭空间x当它找不到值时x用于像我这样的作业class Incr做过?请注意,我并不是在问如何使该功能发挥作用。我知道如果我执行以下操作,该功能将会起作用:

x = 1

def incr():
    global x
    print(x)
    x = x + 1
    print(x)

incr()

这将正确打印:

1
2

正如我所期望的那样。我只想问的是为什么它不只是拉x当关键字来自封闭范围global不像我上面的班级那样存在。为什么口译员觉得有必要将此报告为UnboundLocalError当它清楚地知道某些x存在。由于该函数能够读取值x对于打印,我知道它有x作为其封闭范围的一部分......那么为什么这不能像类示例那样工作呢?

为什么使用的值x打印与使用其值进行赋值有何不同?我就是不明白。


类和函数不同,类内部的变量实际上被分配到类的命名空间作为其属性,而函数内部的变量只是普通变量,无法在其外部访问。

函数内部的局部变量实际上是在函数第一次解析时决定的,Python不会在全局范围内搜索它们,因为它知道你将其声明为局部变量。

所以,一旦 python 看到x = x + 1(作业)并且没有global声明该变量,那么 python 将不会在全局或其他范围中查找该变量。

>>> x = 'outer'
>>> def func():
...     x = 'inner'  #x is a local variable now
...     print x
...     
>>> func()
inner

常见问题:

>>> x = 'outer'
>>> def func():
...     print x       #this won't access the global `x`
...     x = 'inner'   #`x` is a local variable
...     print x
...     
>>> func()
...
UnboundLocalError: local variable 'x' referenced before assignment

但是当你使用一个global语句然后 python for 在中查找该变量global scope.

Read: 当变量有值时,为什么我会收到 UnboundLocalError? http://docs.python.org/2/faq/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value

nonlocal:对于嵌套函数,您可以使用nonlocalpy3.x 中的语句用于修改在封闭函数中声明的变量。


但类的工作方式不同,变量x在类内部声明A实际上变成A.x:

>>> x = 'outer'
>>> class A:
...    x += 'inside'  #use the value of global `x` to create a new attribute `A.x`
...    print x        #prints `A.x`
...     
outerinside
>>> print x
outer

您还可以直接从全局范围访问类属性:

>>> A.x
'outerinside'

Using global在班上:

>>> x = 'outer'
>>> class A:
...     global x
...     x += 'inner' #now x is not a class attribute, you just modified the global x
...     print x
...     
outerinner
>>> x
'outerinner'
>>> A.x
AttributeError: class A has no attribute 'x'

函数的陷阱不会在类中引发错误:

>>> x = 'outer'
>>> class A:
...     print x                      #fetch from globals or builitns
...     x = 'I am a class attribute' #declare a class attribute
...     print x                      #print class attribute, i.e `A.x`
...     
outer
I am a class attribute
>>> x
'outer'
>>> A.x
'I am a class attribute'

LEGB规则:如果没有global and nonlocal使用然后 python 按此顺序搜索。

>>> outer = 'global'
>>> def func():
        enclosing = 'enclosing'
        def inner():
                inner = 'inner'
                print inner           #fetch from (L)ocal scope
                print enclosing       #fetch from (E)nclosing scope
                print outer           #fetch from (G)lobal scope
                print any             #fetch from (B)uilt-ins
        inner()
...         
>>> func()
inner
enclosing
global
<built-in function any>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么Python中的函数可以打印封闭范围内的变量,但不能在赋值中使用它们? [复制] 的相关文章

  • 使用 mmap 将正则表达式应用于整个文件

    我正在尝试使用以下代码将正则表达式应用于整个文件 不仅仅是每一行 import mmap re ifile open ifilename data mmap mmap ifile fileno 0 print data mo re sear
  • Python 中的 if len(list)

    我正在将 Python 代码转换为 C 代码 以便利用 HPC 系统上可用的并行性 最初的程序员在 Python 中使用了一个令我困惑的条件 if rnum lt gt current res alim 0 if len f alim f
  • 无法通过 pip 安装 xmlsec

    我在运行时收到以下信息pip install xmlsec在 macOS Big Sur 11 3 1 中 Building wheels for collected packages xmlsec Building wheel for x
  • Matlab 和 Python 中的优化算法(dog-leg trust-region)

    我正在尝试使用 Matlab 和 Python 中的狗腿信赖域算法求解一组非线性方程 在Matlab中有fsolve https www mathworks com help optim ug fsolve html其中此算法是默认算法 而
  • 在 SQLAlchemy 中选择 NULL 值

    这是我的 PostgreSQL 表 test gt create table people name varchar primary key marriage status varchar test gt insert into peopl
  • 多输出回归问题的多重损失

    所以我试图训练一个 CNN 模型来预测 4 个实值输出 回归问题 我尝试使用均方误差作为损失函数 我的问题是我是否将输出层分支为 4 个不同的输出层 其中有 4 个不同的输出层由于最后一层的权重是单独更新的 loss 4 MSE 确实可以使
  • 修改Keras中的层权重

    我正在尝试修改 Keras 中某个层的输出 我有一个编码器 它将时间序列转换为潜在空间 之后 对于每个压缩的时间序列 我想向时间序列添加一些数字 例如我有 input d Input 100 h1 d Reshape 100 1 input
  • 如何为python虚拟环境设置特定的python版本? [复制]

    这个问题在这里已经有答案了 我是 python 的新手 我正在尝试为我的项目添加一个新环境 该环境在我当前的环境 Python 3 7 5 上运行良好 添加所有依赖项后 我遇到了 pyttsx3 包的问题 用于 python 文本到语音 进
  • 如何使用 python 子进程杀死性能记录?

    我正在尝试使用性能实用程序 https www brendangregg com perf html监视我的系统 它将在 python 脚本中启动和终止 我创建了一个沙箱 如下所示 extra params F 99 g a record
  • 在没有 paramiko 的情况下通过 python 运行 ssh 时,“伪终端不会被分配,因为 stdin 不是终端”

    我在 Python 中运行 ssh 而不使用像 Paramiko 这样的外部库 我这样做有我的理由 而不是通过外部库 基本上我正在做subprocess Popen ssh t bla command 执行此操作时我收到以下消息 Pseud
  • Django:503 服务不可用

    Related 我对 Python 及其框架完全陌生 在学习了一些 Python 基础知识后 我只是尝试一下 Django Problem 现在我正在尝试在第一次安装后运行 Django 服务器 服务器运行没有任何错误 但是当我尝试访问该网
  • Python带有负数的排序列表[重复]

    这个问题在这里已经有答案了 为了尝试通过练习来学习Python 我正在尝试使用Python来实现和测试快速排序算法 实现本身并不困难 但是排序的结果有点令人费解 当我对列表进行排序时 35 1 2 7 8 3 4 20 6 53 结果给了我
  • functools.partial 想要使用位置参数作为关键字参数

    所以我试图理解partial import functools def f x y print x y g0 functools partial f 3 g0 1 4 Works as expected In g1 functools pa
  • Django 查询集和生成器

    出乎意料的是 我想知道以下使用生成器迭代结果集的方式是否会对正常迭代产生任何积极或消极的影响 eg def all items generator for item in Item objects all yield item for it
  • 在标准 python 线程中发出信号

    我有一个线程应用程序 其中有一个网络线程 UI 部分通过callback到这个线程 线程是一个normalpython 线程 它是NO QThread 是否可以在该线程内发出 PyQT Slot 不 不可能像这样从 python 线程发出
  • 检查单元测试中是否调用了 Timer.cancel

    我正在使用threading Timer包在 x 秒后执行方法 但是 在某些情况下 我想提前执行此方法并取消计时器 因此不会调用两次 我如何对此进行单元测试 我想知道计时器是否已停止 以便不再调用该方法 我现在使用以下代码 不幸的是is a
  • 使用 NumPy 函数计算 Pandas 的加权平均值

    假设我们有一个像这样的 pandas 数据框 a b id 36 25 2 40 25 3 46 23 2 40 22 5 42 20 5 56 39 3 我想执行一个操作 a div b 然后按 id 分组 最后使用 a 作为权重计算加权
  • Tensorflow:为什么 tf.case 给我错误的结果?

    我正在尝试使用tf case https www tensorflow org api docs python tf case https www tensorflow org api docs python tf case 有条件地更新张
  • JSF 1.2:如何在同一视图上的回发中保持请求范围的托管 bean 处于活动状态?

    是否可以在同一页面上的回发过程中保持请求作用域的 bean 处于活动状态 一般的问题是 bean 在请求结束时被丢弃 并在每次表单提交时重新创建 例如动态操作背后的布尔值disabled readonly and rendered重置为默认
  • 访问 django for 循环中的元素

    我有一个 Django 模板 其中包含以下代码 该模板创建多个按钮并尝试通过单击 在同一按钮上 删除 隐藏其中一个按钮 for h in helicopters div class btn group div

随机推荐