当我调用一个函数时,我希望能够在函数中定义动态变量名,就像这样......
def build_ports(portlist):
for idx, portname in enumerate(portlist):
chassis, slot, port = portname.split('/')
vartxt = "p%i" % idx
locals()[vartxt] = Port() # Class defining a port object
locals()[vartxt].port_method1(chassis, slot, port)
if idx > 5:
locals()[vartxt].port_method2() # Only call this object method, if idx > 5
但是我们都知道locals()
是只读的,与globals()
不同...所以解释器在看到locals()[vartxt]
时就会bar ... ...
有没有办法在方法中定义动态变量而不会污染全局命名空间(或者更糟糕的是,在方法中使用全局变量时,从未在该方法中定义过它)?
答案 0 :(得分:6)
使用列表而不是称为变量变量的疯狂。
def build_ports(portlist)
ports = []
for idx, portname in enumerate(portlist):
ports.append(Port())
ports[-1].port_method1()
if idx > 5:
ports[-1].port_method2()
您可以改为废弃未使用的ports[-1]
迭代变量并创建本地portname
,而不是使用portname = Port()
,使用它来调用方法,然后将其附加到ports
} 在末尾。 portlist
还是什么?
答案 1 :(得分:3)
不,这是不可能的。如果你看看Python如何存储局部变量,你可以看到原因。
全局变量存储在散列表中,该散列表是动态大小的,并且名称被编译为散列键(用Python术语,实习字符串)。这使得全局查找相对“慢”,但由于需要从其他编译单元(模块)中按名称查找全局变量,因此需要:
# a.py
x = 3
# b.py
import a
a.x = 4 # b needs to know how to find the same x!
局部变量存储在固定大小的数组中,名称被编译为数组索引。
当您查看字节码时可以看到这一点,该字节码对于本地有LOAD_FAST和STORE_FAST,但对于全局变量有LOAD_GLOBAL和STORE_GLOBAL。它也会在您获得的不同异常中泄漏。未找到时,Globals会涓流并生成NameError,但未定义的locals会被空槽检测到,从而产生UnboundLocalError。
def foo():
a
a = 1
foo()
Traceback (most recent call last):
File "<stdin>", line 1, in foo
UnboundLocalError: local variable 'a' referenced before assignment
def foo():
a = 1
foo()
Traceback (most recent call last):
File "<stdin>", line 1, in foo
NameError: global name 'a' is not defined
因为数组是固定大小的,并且在编译函数时计算了大小,所以不能创建任何其他本地数据。
如果您需要更多“本地人”,则需要将值存储为对象的命名属性或字典;显然,这也将抵消速度效益。
答案 2 :(得分:-1)
查看exec。
编辑:是的,我的意思是执行。