Python:设置属于导入模块命名空间的变量

时间:2014-07-17 04:29:02

标签: python namespaces

假设我有一个模块params.py,其中声明了一堆变量:

a = 0.2
b = 0.4
...

在使用此模块时,我想用*导入其命名空间以便于引用。但在这种情况下,似乎我只能访问参数的值,但无法重置它们:

from params import *
def test1():
    print(a)  #this works: printing out the value of params.a

def test2():
    a= 0.5  #doesn't work: does not change the value of params.a 

尝试将变量引用为params.a = 0.5也不起作用(将NameError作为" params"未定义)

我的问题:如何设置/重置以这种方式导入的变量的值?

2 个答案:

答案 0 :(得分:3)

a = 0.5范围内分配test2()仅限于该功能。

您要做的是在模块上设置属性。

示例:

import params

def test1():
    print(params.a)

def test2():
    params.a = 0.5

请参阅:Short Description of Python's Scoping Rules

注意:认识到Python中的所有内容都是某种类型的对象并且通常具有属性可能会有所帮助。这包括模块,类,类的实例,函数等。

更新:虽然不鼓励这样做会“完全”按照您的意图行事:

foo.py:

from params import *  # noqa


def test1():
    print(a)


def test2():
    global a

    a = 0.5

params.py:

a = 1

演示:

$ python -i foo.py
>>> test1()
1
>>> test2()
>>> test1()
0.5
>>>

更新II:但是,我仍然指出,如我的评论所述,这实际上并没有改变params.a引用。参见:

$ python -i foo.py
>>> id(params.a)
140602494749016
>>> id(a)
140602494749016
>>> test1()
1
>>> test2()
>>> test1()
0.5
>>> id(params.a)
140602494749016
>>> id(a)
140602494760472
>>>

摘要:请一般使用此处提供的第一个选项。

答案 1 :(得分:1)

嗯,刚出现的简单解决方案是为同一个模块提供2个import语句:

from params import *
import params

第一个语句允许我访问变量的值而不必使用"params."前缀,第二个允许我在需要时重新绑定变量

params.a = 0.5

我不知道这是否符合最佳做法(可能不符合)。但据我所知,它完成了这项工作。其他建议是受欢迎的。

修改:这不起作用,因为a的值不会反映更新的值:

print(a)  #say it prints 0.2
params.a = 0.5
print(a) # will still print 0.2
print(params.a) #will print 0.5

所以这里的教训是,如果您使用from params import a导入变量,那么即使它在原始版本中发生了变化,您仍然会使用a的值。即它是按价值进口而非参考。