这里有一个简单的文件,描述了一些不一致的Python (3.6)行为。为什么Case 1和Case 2有可能运行,但Case 3却失败了,即使Case 3只是前两种情况的合并?
我提供了前两种情况的dis输出。
import dis # Python bytecode disassembler
class A(object):
def __init__(self):
self.x # In case 2 (and 3), getting x results in a function call (because they are @properties), which fails when instantiating A because y is undefined. Case 1 evaluates the reference to a function without calling it and so it does not raise an exception.
# CASE 1: Legal
def x(self):
y
pass
'''
# CASE 2: Legal
@property
def x(self):
pass
'''
'''
# CASE 3: Illegal:
@property
def x(self):
y
pass
'''
if __name__ == '__main__':
a = A()
dis.dis(A)案例1字节码:
Disassembly of __init__:
5 0 LOAD_FAST 0 (self)
2 LOAD_ATTR 0 (x)
4 POP_TOP
6 LOAD_CONST 0 (None)
8 RETURN_VALUE
Disassembly of x:
9 0 LOAD_GLOBAL 0 (y)
2 POP_TOP
10 4 LOAD_CONST 0 (None)
6 RETURN_VALUE案例2字节码:
Disassembly of __init__:
5 0 LOAD_FAST 0 (self)
2 LOAD_ATTR 0 (x)
4 POP_TOP
6 LOAD_CONST 0 (None)
8 RETURN_VALUE发布于 2017-06-28 23:25:08
感谢@chepner的评论:
在第1种情况下,您没有调用任何东西;Sel.x是一个未使用的函数引用。在第3种情况下,Sel.x实际上调用了定义的getter for x,这可能是为了访问一个未定义的全局名称。
案例3中由行self.x引起的行为与案例1有根本的不同,因为案例1没有调用任何东西--它只是计算对函数的引用。
另一方面,在第3种情况下,self.x执行x方法的主体,导致未定义的y错误。
为了确认@chepner的评论,我用case 1运行了a.x(),得到了与案例3相同的错误。
发布于 2017-06-28 23:12:52
这里没有矛盾之处。
当您实例化a = A()时,调用__init__,它调用self.x,它将执行x的主体。此时,不存在y inscope,因此您将得到一个异常。
https://stackoverflow.com/questions/44813771
复制相似问题