Python【知识点】傻傻的函数内变量

问题的由来

有个学生问我一个问题关于函数内部变量的我们来一起看下代码:

Code1

 1 x = 50
 2 
 3 
 4 def func():
 5     print(x)
 6     global x
 7     print("x修改前的值:", x)
 8     x = 2
 9     print("x修改后的值:", x)
10 
11 func()
12 
13 """
14 输出结果为:
15 50
16 x修改前的值: 50
17 x修改后的值: 2
18 """

我们知道我们要在函数内部修改全局变量必须使用global才可以?那我们看下面的代码

Code2

 1 test_dict = {"name": "luotianshuai", "age": 18}
 2 
 3 
 4 def func():
 5     print(test_dict)
 6     print("修改前:", test_dict)
 7     test_dict["age"] = 16
 8     print("修改后:", test_dict)
 9 
10 func()
11 
12 """
13 输出结果:
14 {'name': 'luotianshuai', 'age': 18}
15 修改前: {'name': 'luotianshuai', 'age': 18}
16 修改后: {'name': 'luotianshuai', 'age': 16}
17 """

额?问题来了为什么不用global我就可以修改全局变量呢?

问题解释

在Code1代码中

 1 x = 50
 2 
 3 
 4 def func():
 5     x = 2
 6     """
 7     x = 2 这段代码是有歧义的,因为它即可表示引用全局变量x,也可以表示创建一个局部变量
 8     所以在python中,默认它的行为是创建局部变量,除非显式声明global.
 9     """
10 
11 func()

在Code2代码中

test_dict = {"name": "luotianshuai", "age": 18}


def func():
    print(test_dict)
    print("修改前:", test_dict)
    test_dict["age"] = 16
    """
    test_dict["age"] 它是“明确的”,因为如果把d当作是局部变量的话,它会报KeyError
    所以它只能是引用全局的d,故不需要多此一举显式声明global。
    """
    print("修改后:", test_dict)

func()

 总结:

从上面的结果看,我们思考可以得出一个结论,函数内部是否可以直接修改全局变量的本质就是"它是否是明确的"

仔细想想,就会发现不止dict不需要global,在函数内部所有”明确的“东西都不需要global。

因为int类型str类型之类的,只有一种修改方法,即x = y, 恰好这种修改方法同时也是创建变量的方法,所以产生了歧义,不知道是要修改还是创建。

而dict/list/对象等,可以通过dict['x']=y或list.append()之类的来修改,跟创建变量不冲突,不产生歧义,所以都不用显式global。

posted @ 2017-04-27 17:02 Mr.心弦 阅读(...) 评论(...) 编辑 收藏