Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在函数中分配变量:奇怪的行为_Python - Fatal编程技术网

Python 在函数中分配变量:奇怪的行为

Python 在函数中分配变量:奇怪的行为,python,Python,我很少使用Python,所以我不清楚为什么允许这种行为: 没有w对象,因此它没有s属性,那么为什么f允许进行w.s赋值 >>> def f(): w.s="ads" #allows, no exception >>> w.s="sds" #outside function Traceback (most recent call last): File "<pyshell#74>", line 1, in <module>

我很少使用Python,所以我不清楚为什么允许这种行为: 没有w对象,因此它没有s属性,那么为什么f允许进行
w.s
赋值

>>> def f():
    w.s="ads"  #allows, no exception
>>> w.s="sds"  #outside function
Traceback (most recent call last):
  File "<pyshell#74>", line 1, in <module>
    w.s="sds"
NameError: name 'w' is not defined
>>def():
w、 s=“ads”#允许,无例外
>>>w.s=“sds”#外部功能
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
w、 s=“sds”
NameError:未定义名称“w”

试着运行函数,看看会发生什么。Python不会在您编写代码时捕获它,但一旦您运行代码,它就会出错

您所看到的是因为python不知道在函数运行时,不会有一个具有属性
s
的对象
w
。但是,当您在函数调用之外执行此操作时,它会检查作用域中是否没有
w
,从而检查是否存在错误

试试这个:

def f():
    w.s = "one"
w.s  = "one" # called before there is such an object
f() # called before w exists, it will error out    

class SomeClass(object):
    def __init__(self):
        self.s = "two"

w = SomeClass()
f() # since w exists it will run

函数尚未运行,因为它尚未被调用,而不是在函数外部将
w.s
赋值给
“sds”

这种行为是允许的,因为Python是一种动态语言。在编译时,当执行
f
函数定义时(即编译为字节码),解释器知道在绑定到名称
w
的函数中没有本地对象,因此
w
必须引用全局对象。当然,当前在全局范围中没有绑定到该名称的对象,但这并不重要:Python假定您知道自己在做什么,除非得到证明:)

我们可以使用该模块来反汇编函数的字节码。这里有一个简短的演示

from dis import dis

def f():
    w.s = "ads"

dis(f)
print('- ' * 30)

class Test(object):
    pass

try:
    f()
except Exception as e:
    print(e)

w = Test()
f()
print(w.__dict__)
输出

 40           0 LOAD_CONST               1 ('ads')
              3 LOAD_GLOBAL              0 (w)
              6 STORE_ATTR               1 (s)
              9 LOAD_CONST               0 (None)
             12 RETURN_VALUE
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
name 'w' is not defined
{'s': 'ads'}
name 'w' is not defined
{}
FWIW,在Python 2中,
f
的字节码是相同的,但是
NameException
错误消息是
未定义全局名称“w”

因此,如果我们尝试在调用时在全局范围内调用
f()
而没有有效的
w
,我们将得到一个异常,但是如果有一个有效的
w
则一切正常

请注意,
w
必须在全局范围内,另一个函数内的局部
w
将不起作用。例如:

def f():
    w.s = "ads"

class Test(object):
    pass

def g():
    w = Test()
    try:
        f()
    except Exception as e:
        print(e)
    print(w.__dict__)

g()
输出

 40           0 LOAD_CONST               1 ('ads')
              3 LOAD_GLOBAL              0 (w)
              6 STORE_ATTR               1 (s)
              9 LOAD_CONST               0 (None)
             12 RETURN_VALUE
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
name 'w' is not defined
{'s': 'ads'}
name 'w' is not defined
{}

一旦调用
f()
它将显示相同的错误。除非你没有调用它,否则它不会显示任何错误。对不起,我在匆忙中发布了我的答案,在清除“NameError”后意识到了这一点。非常感谢。