我很少使用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
答案 0 :(得分:5)
尝试运行您的功能,看看会发生什么。 Python在编写代码时并没有捕获它,但是一旦运行代码就会出错。
你看到的是因为python不知道当你的函数运行时,它不会成为具有属性#Python 2.7
import string
companyName = string.replace(companyName, "'", "")
的对象w
。但是,当您在函数调用之外执行此操作时,它会检查范围中是否存在s
,从而检查错误。
试试这个:
w
答案 1 :(得分:4)
函数尚未运行,因为它尚未被调用,而不是在函数外部完成w.s
到"sds"
的分配。
答案 2 :(得分:2)
这种行为是允许的,因为Python是一种动态语言。在编译时,当执行f
函数定义(即,编译为字节代码)时,解释器知道函数中没有绑定到名称w
的本地对象,因此{{1必须引用一个全局对象。当然,当前在全局范围内没有绑定到该名称的对象,但这并不重要:Python假设您知道自己在做什么,直到证明不是这样:)。
我们可以使用dis
模块来反汇编函数的字节代码。这是一个简短的演示。
w
<强>输出强>
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__)
FWIW,在Python 2中, 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'}
的字节代码相同,但f
错误消息为
NameException
。
因此,如果我们在调用时尝试在全局范围内调用global name 'w' is not defined
而没有有效的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()