python 类 作用域_Python类作用域规则

TL;DR:这种行为从python2.1PEP 227: Nested Scopes就已经存在了,并且在那时就已经知道了。如果一个名称在类主体中被赋值(比如y),那么它就被认为是一个局部/全局变量;如果它没有被赋值给(x),那么它也可能指向一个闭包单元。词法变量不会作为类主体的局部/全局名称显示。在

在Python3.4上,dis.dis(func)显示了以下内容:>>> dis.dis(func)

4 0 LOAD_CONST 1 ('xlocal')

3 STORE_DEREF 0 (x)

5 6 LOAD_CONST 2 ('ylocal')

9 STORE_FAST 0 (y)

6 12 LOAD_BUILD_CLASS

13 LOAD_CLOSURE 0 (x)

16 BUILD_TUPLE 1

19 LOAD_CONST 3 ()

22 LOAD_CONST 4 ('C')

25 MAKE_CLOSURE 0

28 LOAD_CONST 4 ('C')

31 CALL_FUNCTION 2 (2 positional, 0 keyword pair)

34 STORE_FAST 1 (C)

37 LOAD_CONST 0 (None)

40 RETURN_VALUE

LOAD_BUILD_CLASS在堆栈上加载builtins.__build_class__;这是用参数__build_class__(func, name)调用的;其中func是类主体,name是{}。类主体是函数func的常量#3:

^{pr2}$

在类主体中,x是用LOAD_CLASSDEREF(15)访问的,而y是用LOAD_NAME(25)加载的。LOAD_CLASSDEREF是一个python3.4+操作码,用于从类主体内的闭包单元加载值(在以前的版本中,使用了泛型的^{);而{}用于从局部变量加载值,然后从全局加载值。然而,闭合单元既不显示为局部的,也不显示为全局的。在

现在,由于名称y存储在类主体(35)中,因此它一直被用作本地/全局名称而不是闭包单元。

闭包单元不显示为类主体的局部变量。在

自PEP 227以来的唯一变化是在Python3中添加了nonlocal;如果在类主体中使用它,那么类主体可以设置包含范围内单元格的值:x = "xtop"

y = "ytop"

def func():

x = "xlocal"

y = "ylocal"

class C:

nonlocal y # y here now refers to the outer variable

print(x)

print(y)

y = 1

print(y)

print(C.y)

func()

现在的输出是xlocal

ylocal

1

Traceback (most recent call last):

File "test.py", line 15, in

func()

File "test.py", line 13, in func

print(C.y)

AttributeError: type object 'C' has no attribute 'y'

也就是说,print(y)读取包含范围的单元格y的值,y = 1设置该单元格中的值;在这种情况下,没有为类C创建属性。在

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值