在方法中动态定义局部变量的最佳方法是什么

时间:2011-04-15 12:08:31

标签: python

当我调用一个函数时,我希望能够在函数中定义动态变量名,就像这样......

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 ... ...

有没有办法在方法中定义动态变量而不会污染全局命名空间(或者更糟糕的是,在方法中使用全局变量时,从未在该方法中定义过它)?

3 个答案:

答案 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

编辑:是的,我的意思是执行。