Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.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_Python 3.x_Function - Fatal编程技术网

Python 导入模块中的全局变量

Python 导入模块中的全局变量,python,python-3.x,function,Python,Python 3.x,Function,我有以下代码: one.py import two as t t.test1() t.test2() class test_class(): def __init__(self,arg): print("created obj name is {}".format(arg)) self.name = arg non_global ="initial global" obj = test_class("test name") def tes

我有以下代码:
one.py

import two as t 

t.test1()

t.test2()
class test_class():
    def __init__(self,arg):
        print("created obj name is {}".format(arg))
        self.name = arg

non_global ="initial global"

obj = test_class("test name")



def test1():
    print("\t in test 1")
    print (obj.name)
    global non_global # wont work without global keyword, value still refers to "initial value"
    print(non_global) # initial value
    obj.name = "changed"
    #non_global = "changed global"


def test2():
    print("\tin test 2")
    print(obj.name)
    print(non_global)
two.py

import two as t 

t.test1()

t.test2()
class test_class():
    def __init__(self,arg):
        print("created obj name is {}".format(arg))
        self.name = arg

non_global ="initial global"

obj = test_class("test name")



def test1():
    print("\t in test 1")
    print (obj.name)
    global non_global # wont work without global keyword, value still refers to "initial value"
    print(non_global) # initial value
    obj.name = "changed"
    #non_global = "changed global"


def test2():
    print("\tin test 2")
    print(obj.name)
    print(non_global)
结果是:

created obj name is test name
         in test 1
test name
initial global
        in test 2
changed
changed global
如果我在
test1()
中更改为:

def test1():
    print("\t in test 1")
    print (obj.name)
    #global non_global # wont work without global keyword, value still refers to "initial value"
    print(non_global) # initial value
    obj.name = "changed"
    non_global = "changed global"
我在打印行上得到赋值前引用的错误
UnboundLocalError:local变量“non_global”

如果我评论
non_global=“changed global”
错误就会消失

我的问题是:


为什么这会发生在
非全局
而不是
obj
?我使用的是
python3.5

不同之处在于
非全局
是一个变量赋值,而
obj.name
是一个属性赋值

函数中的变量赋值使该变量成为局部变量,因此Python不会在局部范围之外的任何地方查找该变量,因此
print(non_global)
失败,因为它尚未在该范围内定义。这是用<代码> Global < /Cord>语句进行的,因为使用<代码> Global < /Cord> >您在告诉Python不要将它视为局部变量,因此它的值可以从全局范围获取。 当解析函数体时,将决定是否将变量转换为局部变量,因此在实际声明之前尝试使用该变量的时间将在运行时出现错误

obj.name
另一方面,基本上使用simple搜索
obj
,然后使用指定的值设置
name
属性

同样,您也可以在函数体中更新全局可变数据结构(列表、dict等),而无需使用
global

除了
=
,像
*=
+=
这样的增广赋值也使变量成为局部变量

a = []

def func1():
    a += ['foo']

def func2():
    a.extend(['bar'])

def func3():
    a[0] += 'spam'


func1()  # Fails with UnboundLocalError: local variable 'a' referenced before assignment

func2()  # works fine

func3()  # Also works fine because a[0] is not a variable. 
         # We are telling Python to look for `a` and fetch its 0th item
         # and concatenate 'spam' to it.

print(a) # prints ['barspam']

字节码反汇编还可以帮助您指出差异:

>>> import dis
>>> dis.dis(func1)
 45           0 LOAD_FAST                0 (a)
              3 LOAD_CONST               1 ('foo')  # Load a local variable name foo
              6 BUILD_LIST               1
              9 INPLACE_ADD
             10 STORE_FAST               0 (a)      # Store local variable named foo
             13 LOAD_CONST               0 (None)
             16 RETURN_VALUE
>>> dis.dis(func2)
 48           0 LOAD_GLOBAL              0 (a)      # Load from global scope
              3 LOAD_ATTR                1 (extend)
              6 LOAD_CONST               1 ('bar')
              9 BUILD_LIST               1
             12 CALL_FUNCTION            1
             15 POP_TOP
             16 LOAD_CONST               0 (None)
             19 RETURN_VALUE
>>> dis.dis(func3)
 51           0 LOAD_GLOBAL              0 (a)      # Load from global scope
              3 LOAD_CONST               1 (0)
              6 DUP_TOPX                 2
              9 BINARY_SUBSCR
             10 LOAD_CONST               2 ('spam')
             13 INPLACE_ADD
             14 ROT_THREE
             15 STORE_SUBSCR
             16 LOAD_CONST               0 (None)
             19 RETURN_VALUE

# Names of local variables or arguments of each function obtained through its code object
>>> func1.__code__.co_varnames
('a',)
>>> func2.__code__.co_varnames
()
>>> func3.__code__.co_varnames
()


相关:

您为什么删除之前的问题,然后重新提问?对
obj.name
的赋值不是对
obj
的赋值。只有对
obj
的赋值才是编译器生成
obj
局部变量的依据。@AndyG我认为格式不够好,问这个问题太仓促了。如果
test1()
的最后一行是
non_global=“changed global”
我就得到了错误。我不明白为什么打印语句后的一行会引起问题。如果这句话被注释了,一切都很好。print语句后面的一行和注释一样好,对吗?@pyjg检查第3段。谢谢,所以函数体被解析,然后逐行执行?我不太明白这个故事flow@pyjg模块或函数的解析会产生字节码,该字节码包含运行时使用的指令。
func1
下的指令是从本地作用域(
load\u FAST
)加载
a
,但该变量当时不存在,因此我们得到了
UnboundLocalError
。查看您提供的链接,现在它更有意义了。非常感谢。