我正试图理解为什么其中一个失败而另一个成功。
my_prd = { 'server': 'prd.my.company.com' }
my_lab = { 'server': 'prd.my.company.com' }
my_srv = {}
def test_fails(which):
if which == 'prd':
my_srv = my_prd
else:
my_srv = my_lab
def test_works(which):
if which == 'prd':
my_srv['server'] = my_prd['server']
else:
my_srv['server'] = my_lab['server']
输出:
fails: my_srv={}
works: my_srv={'server': 'prd.my.company.com'}
我要把我的引用逻辑移到我的函数之外来处理这个问题,但我想了解为什么my_srv
在足够的范围内,我可以给它赋值,但在范围内不足以被引用或copy()
?
在test_fails()
中,您分配my_srv = my_prd
(或my_srv = my_lab
)。这意味着my_srv
是一个指向my_prd
的变量,就像我们所说的"指针"一样。在其他语言中(在Python中,"一切都是指针")。您可以将my_srv
用于test_fails()
的其余部分,但是一旦离开该函数,该局部变量将被遗忘,并且my_srv
将再次引用空字典。
也许这将有助于你所希望做的:
>>> my_prd = { 'server': 'prd.my.company.com' }
>>> my_lab = { 'server': 'prd.my.company.com' }
>>> my_srv = {}
>>> def test_fails(which):
... if which == 'prd':
... my_srv = my_prd
... else:
... my_srv = my_lab
... my_srv["key"] = "item"
...
>>> print(my_prd)
{'server': 'prd.my.company.com'}
>>> test_fails("prd")
>>> print(my_prd)
{'server': 'prd.my.company.com', 'key': 'item'}
当您在函数中创建变量时,该变量默认为本地变量,这意味着一旦您退出该函数,该变量将不复存在(并且不会与全局变量存储在同一位置,因此具有相同名称的全局变量和局部变量不是问题),这就是您通过编写
所做的my_srv = my_prd
当你退出test_fails()并访问my_srv时,python会在全局变量中查找my_srv,它发现my_srv未被修改并且等于{},全局my_srv和本地my_srv从来没有关联,它们只是碰巧有相同的名称,但总是驻留在两个不同的环境中。
然而,在test_works()中,您不创建任何变量,您告诉python在已经存在的字典中创建一个额外的键/值对,my_srv全局变量,因此当您退出test_works()时,您的工作仍然存在。
正如其他人提到的,Python默认创建局部变量。有一些关键字,如global和nonlocal (Python 3.x)可以改变名称空间的处理方式。编辑:
在我的例子中,这行得通:
def test_fails(which):
global my_srv #<<< Add this and it will work
if which == 'prd':
my_srv = my_prd
else:
my_srv = my_lab
我找到的一个很好的参考是:全局变量与局部变量和命名空间