[python]变量作用域问题

先列出参考链接:
python变量作用域–作者:lovingprince
python开发杂货铺:作用域的痛点—作者:Assassin
python中在哪些情况下必须使用global来声明全局变量
python程序员的10个常见问题

在对象内部访问外部变量

python能够改变变量作用域的代码段是def、class、lamda.
其实python内一切皆对象,函数也是对象,所以总结起来就是,一个对象内部的变量就是局部变量,外部的python默认都是全局变量,也就是函数可以随便访问,甚至可以修改列表,但是不能修改值,也就是说x=xxx这种语句是会报错的,举例:

def test1():
    print(a)
a = 'a'
test1()
>>
a
def test1():
    a[2] = 'x'
    print(a)
a = [1,2,3]
test1()
>>
[1,2,'x']

所以要小心这个坑,不要一不小心在函数内部改变了全局变量自己还不知道

>>> x = 10
>>> def foo():
...     x += 1
...     print x
...
>>> foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in foo
UnboundLocalError: local variable 'x' referenced before assignment
>>> lst = [1, 2, 3]
>>> def foo1():
...     lst.append(5)   # 这没有问题...
...
>>> foo1()
>>> lst
[1, 2, 3, 5]

>>> lst = [1, 2, 3]
>>> def foo2():
...     lst += [5]      # ... 这就有问题了!
...
>>> foo2()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in foo
UnboundLocalError: local variable 'lst' referenced before assignment

python的作用域链

#终极版作用域

name = "lzl"

def f1():
    print(name)

def f2():
    name = "eric"
    f1()

f2()
>>
lzl

python的作用域是先从内部开始找,再向外扩展,寻找全局变量
输出为外部的值,此时f2()与f1()作用域是并列的,也就是说,python的作用域不会产生函数内的嵌套问题,不是函数自身内的作用域,就会向外找全局变量,除非你在一个函数定义中定义另一个函数,会产生作用域嵌套,因为在定义的时候,对象之间就有了隶属关系

def f1():
    def f2():
        print(name)
    name = 'Jefrey'
    return f2()
f1()

# Jefrey

这太变态了,应该没有人会这么写代码来定义函数~!!!不过这只是用函数举例,在实际中很有可能局要定义对象嵌套的数据结构

在对象外部访问对象内部局部变量

方法1:global

对于一个全局变量,你的函数里如果只使用到了它的值,而没有对其赋值(指a = XXX这种写法)的话,就不需要声明global。相反,如果你对其赋了值的话,那么你就需要声明global。声明global的话,就表示你是在向一个全局变量赋值,而不是在向一个局部变量赋值。

def test1():
    global a
    a = a+1
    print(a)
name = "lzl"
a = 0
test1()
>>
1

方法2:在函数内部或者甚至函数外部增加函数这个对象的一个属性

def testvalue():
    testvalue.x = 1

def test2():
    testvalue.y = 1
testvalue()
test2()
testvalue.x = testvalue.x+1
testvalue.y = testvalue.y+1
print(testvalue.x)
print(testvalue.y)
>>
2
2

猜你喜欢

转载自blog.csdn.net/qq_23269761/article/details/78408181