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

如果我运行以下代码:

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存在时,为什么会觉得需要将其报告。由于该函数能够读取at处的值以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在global范围内查找该变量。

阅读:当变量具有值时,为什么会收到UnboundLocalError?

:对于嵌套函数,您可以使用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'

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'


规则:如果没有globalnonlocal被使用,则蟒蛇搜索顺序。

>>> 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>

以上是 为什么Python中的函数可以在封闭范围内打印变量,但不能在赋值中使用它们? 的全部内容, 来源链接: utcz.com/qa/413767.html

回到顶部