内部变量是否比全局变量具有更高的优先级?

Does an internal variable have more priority than a global variable?

我发现了一个关于内部变量的奇怪代码,我不明白其行为:

artist = "ABBA"

def printer(artist):
    global internal_var 
    internal_var= "Queen"
    print(artist,"is an artist")

internal_var = "U2" # I added this line

printer(artist) 
printer(internal_var) # I thought this would be "U2" ...

print(internal_var) # I added this line; I thought this would be "U2" ...

输出为:

ABBA is an artist
Queen is an artist
Queen

我完全糊涂了。
首先,为什么这不会导致冲突?
其次,为什么 internal_var 没有被覆盖?
第三,如何覆盖 internal_var?

我觉得在一定程度上是可以用的,但是会产生更多的bug。

请告诉我这个问题是否重复。
(我找不到任何类似的问题。)
提前谢谢你。

Firstly, why doesn't this lead to a conflict? Secondly, why isn't internal_var overwritten? Thirdly, how can I overwrite internal_var?

def printer里面的internal_var和全局作用域的internal_var同名,确实存在“冲突”。由于您使用了 global 关键字,因此通过让两个作用域都引用在全局作用域中定义的值来解决冲突。通常,局部变量“隐藏”任何具有相同名称的全局范围变量(即为局部范围创建不同的值,并且全局范围变量变得不可访问)。

如果您所说的“覆盖”是指重新分配其值 - 它是。这就是为什么您在输出的列表行中看到“Queen”的原因。

如果您的意思是“覆盖”,如上述具有不同值的“隐藏”,那是因为您使用了 global 关键字,因此明确禁止局部变量隐藏全局变量。

I think it's usable to a certain extent, but it will produce more bugs.

是的。 使用 global 关键字就是我所说的“代码味道”——这是你应该(几乎?)永远不会做的事因为它大大增加了出现神秘错误的机会。如果您刚刚起步,我建议您不惜一切代价避免使用它,并且对您看到的任何使用它的教程持怀疑态度,除非它是在教您它如何工作的课程的上下文中(以防您在建议您永远不要实际使用它之前必须调试别人的代码)。 :)

在代码中添加了一些注释,以阐明其工作原理:

artist = "ABBA"

def printer(artist):
    global internal_var 
    internal_var= "Queen"
    print(artist,"is an artist")

internal_var = "U2" # I added this line; this line define global variable internal_var and set "U2"  
# note till this point we have two global variables as: (1) artist="ABBA" and  (2) internal_var= "U2"
print(internal_var) # display "U2" 

printer(artist) # internal_var is changed by printer to "Queen" because using global inside printer as "global internal_var" means you are referring to global variable internal_var.  
print(internal_var) # display "Queen"

printer(internal_var) # I thought this would be "U2" ... Note: you pass "Queen" not "U2", this prints "Queen" and change "Queen" to "Queen" again

print(internal_var) # I added this line; I thought this would be "U2" ... Note: internal_var is "Queen" not "U2"