python函数命名空间_关于python:函数命名空间概念(在赋值之前引用)

我在函数中查找了Namespace概念的一些解释。

这是一个代码,它将引发UnboundLocalError:局部变量...在赋值之前引用

1

2

3

4x = 1

def foo():

print x

x = 2

我明白这应该引发异常。但我想了解python如何知道变量是在本地命名空间中。在行打印x,x不在局部变量dict中。

1

2

3

4

5

6

7

8

9

10

11

12

13x = 1

def foo():

print 'local before print x : ',locals()

print x

print 'local after print x :',locals()

x = 2

foo() # call function, print local namespace before raising exception

local before print x : {}

Traceback (most recent call last):

File"", line 1, in

File"", line 3, in foo

UnboundLocalError: local variable 'x' referenced before assignment

在打印x之前,本地命名空间dict是空的{}(这是非常明显的)。那么python如何知道x是局部变量。

这与类不同

1

2

3

4

5

6

7

8

9a = [1]

class b():

c = a

a = 2

print 'c inside class ', b.c

'c inside class [1]'

d = b()

在课堂上没有类似案例引发异常。

如果有人可以帮我解释概念,python在赋值之前知道这个变量是局部变量。

我检查了许多表格和网站的解释,但没有找到任何。

有帖子和表格解释如何解决这个案子。例。

UnboundLocalError:在赋值之前引用的局部变量....

但我正在寻找Python工作的背后。

Python将您的代码预编译为一些字节码。在此步骤中,它将找出每个范围(通常是函数)标识符是引用全局变量还是局部变量。

如果它被明确声明为global,则它是全局的(简单情况)。

如果在函数中的任何位置为其分配值而未明确声明global,则它是本地的。

如果仅在函数中读取它,则假定它是全局的(隐式)。

这是在编译时完成的,因此不会执行任何操作来确定这一点。

现在,在运行时,如果在分配之前读取局部变量,则会出现错误。

现在,对于类,您有不同的情况,因为那里的变量不是真正的本地(即位于调用堆栈的内存中)。如果在b的声明中访问a,则将访问module-global变量,除非存在覆盖模块全局变量的类全局变量。如果指定给a,则将创建(或更改)类全局变量。 a(或赋值)的任何后续访问都将访问类全局(或分配给)。

是的我完全同意你的看法。但是当我在打印该变量之前print locals()时,它会给出空字典。那么如果没有本地变量,python会在哪里寻找局部变量。

我不明白如果在函数中有任何赋值,那么每个访问和赋值都将被编译为访问局部变量。如果在运行时发生了赋值,则dict将相应地扩展。如果在分配之前完成访问,则dict将缺少条目,这将引发异常。

我想知道如果该变量在函数中具有赋值,那么python将会显示在某处。我知道python首先在locals()内部检查该变量是否在本地命名空间中,而对于全局命名空间是否为globals()。所以变量python在这种情况下查找。

它不会同时考虑两者。如果编译步骤发现它应该是一个局部变量(使用上面描述的确定性),它将查看locals()。如果变量在编译时确定为全局变量,它将查看globals()。如果它在那里找不到,则抛出异常。如果在locals()中找不到globals(),则没有"回退",反之亦然。

对于可以有局部变量的函数来说,这一切都是正确的。对于课程,你有一个不同的概念;没有"本地"变量,而是类全局变量(与模块全局变量相关)。在这种情况下,你有一个回退和覆盖机制(第一个类 - 全局变量和下面的模块 - 全局变量),你错误地认为它们具有locals和globals的函数。

好的,我明白,该变量在编译时被视为本地变量。我想知道python存储那个信息的位置。对不起,我无法告诉你我到底想问什么。我很感激你的时间。

该信息存储在生成的字节码中。它要么包含用于访问堆栈上的局部变量的代码,要么用于访问全局变量。这使得在运行时很难"找出"(如果这是你的目标,我不确定你的用例,但听起来有点像这样)。您可以在try clase中访问该变量,并在不可用时检查错误。对于局部变量和全局变量,该消息可能不同。

我再次检查了这个。如果您尝试访问尚未设置的局部变量,您将获得UnboundLocalError(继承NameError)。如果您尝试访问尚未设置的全局变量,您将获得纯NameError。所以要区分这两个你可以使用isinstance(e, UnboundLocalError)(或except这个类当然)。如果您还不知道,如果它解决了您的问题,请接受答案(按答案左侧的复选标记)。您还可以提供其他有用的答案(向上三角形留给答案)。

我不接受它,因为你的答案不是我想要的。从你的评论中可以清楚地看到。这就是为什么我投票对你的意见有用。 docs.python.org/2.7/tutorial/让我更清楚。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值