关于变量作用域,运行结果和教材不一样。请教大家。

python作用域 优先顺序

加载变量的优先级顺序依次是:python内置作用域>当前模块中的全局(文件从上而下读取)>外层作用域>局部作用域。
下面例子:
教材标识 结果为 10 (上层函数变量的结果)
我运行的结果为 2 (全局变量的结果)(python 3.7.6)

first1 = 2  # 全局变量
def in_numbers():
    second = 20  # 嵌套的局部变量
    print(first1)
def numbers():
    first1=10  # 局部变量
    in_numbers()
numbers()

请问大家,这个例子中按优先顺序,print结果应该是上层变量结果10,可为什么显示全局结果2 呢?

最佳答案
first1 = 2  # 全局变量
def in_numbers():
    second = 20  # 嵌套的局部变量
    print(first1)
def numbers():
    global first1# 局部变量
    first1 = 10  
    in_numbers()
numbers()
first1 = 2  # 全局变量
def in_numbers():
    second = 20  # 嵌套的局部变量
    print(first1)
def numbers():
    global first1
    first1 = 10# 局部变量
    print(first1)
    in_numbers()
numbers()

结果就为10,你都知道了定义的first1为局部变量,那调用的first1当然是in_numbers函数调用的first1呀,而这个first1是先前你在函数外部定义的。

如果想用全局变量的话,在函数内部需要加上global哦,才能改变

4年前 评论
讨论数量: 7
first1 = 2  # 全局变量
def in_numbers():
    second = 20  # 嵌套的局部变量
    print(first1)
def numbers():
    global first1# 局部变量
    first1 = 10  
    in_numbers()
numbers()
first1 = 2  # 全局变量
def in_numbers():
    second = 20  # 嵌套的局部变量
    print(first1)
def numbers():
    global first1
    first1 = 10# 局部变量
    print(first1)
    in_numbers()
numbers()

结果就为10,你都知道了定义的first1为局部变量,那调用的first1当然是in_numbers函数调用的first1呀,而这个first1是先前你在函数外部定义的。

如果想用全局变量的话,在函数内部需要加上global哦,才能改变

4年前 评论
Jason990420

你是不是改了例子的内容 ? 因为注解中说 second = 20 是嵌套的局部变量

first1 = 2 # 全局变量
def in_numbers():
    second = 20 # 嵌套的局部变量
    print(first1)
def numbers():
    first1=10 # 局部变量
    in_numbers()
numbers()
结果: 2

例子应该是

first1 = 2 # 全局变量
def numbers():
    first1=10 # 局部变量
    def in_numbers():
        second = 20 # 嵌套的局部变量
        print(first1)
    in_numbers()
numbers()
结果: 10
4年前 评论

@娃哈哈店长 明白了。多谢多谢。 嗯嗯。在in_numbers()中变量值,源于全局。因为first1是数值,是不可变类型, 因此numbers()赋值仅在自己内部有效,范围外无效,in_numbers()函数内 仍然是全局的值。除非global指明全局变量,变为地址引用。

多谢您的解答。

4年前 评论

@Jason990420 多谢多谢。 您给出的例子 结果确实是10。

这两个例子对比说明: python作用域 层级的界定,在于“书写层级”,而不是“调用逻辑层级”。

多谢您巧妙的实例。收益良多。

4年前 评论

多谢上面朋友的提示、指点。 大致了解了py的变量作用域。 在此总结了4小例,供大家参考。

“不可变变量”的作用域,实例一:

first1 = 2  # 全局变量
def four():
    print("4th.", first1)
def third():
    # global first1
    first1 = 30  # 局部变量
    print("3th.", first1)
    four()
def second():
    # global first1
    first1=20  # 局部变量
    print("2nd.", first1)
    third()
second()

上例结果
2nd. 20
3th. 30
4th. 2

“不可变变量”的作用域,实例二:

first1 = 2  # 全局变量
def second():
    # global first1
    first1=20  # 局部变量
    print("2nd.", first1)
    def third():
        # global first1
        first1 = 30  # 嵌套的局部变量
        print("3th.", first1)
        def four():
            print("4th.", first1)
        four()
    third()
second()

上例结果
2nd. 20
3th. 30
4th. 30

“可变变量”的作用域,实例一:

first1 = [1, 2, 3]  # 全局变量
def four():
    print("4th.", first1)
def third():
    # global first1
    first1[0] = 30  # 局部变量
    print("3th.", first1)
    four()
def second():
    # global first1
    first1[0] = 20  # 局部变量
    print("2nd.", first1)
    third()
second()

上例结果
2nd. [20, 2, 3]
3th. [30, 2, 3]
4th. [30, 2, 3]

“可变变量”的作用域,实例二:

first1 = [1, 2, 3]  # 全局变量
def second():
    # global first1
    first1[0] = 20  # 局部变量
    print("2nd.", first1)
    def third():
        # global first1
        first1[0] = 30  # 嵌套的局部变量
        print("3th.", first1)
        def four():
            print("4th.", first1)
        four()
    third()
second()

上例结果
2nd. [20, 2, 3]
3th. [30, 2, 3]
4th. [30, 2, 3]

4年前 评论
Jason990420

“可变变量” 的作用域,实例一 & 实例二 没有用到局部变量, 都是全局变量, 跑完打印一下first1, 內容已被改变了.

4年前 评论

@Jason990420 嗯嗯,是。 可变类型,全部地址传递

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!