交叉模块变量

时间:2010-01-07 11:28:33

标签: python import module

来自here我了解了如何使用其他模块中的变量。

这一切都很好
import foo as bar

但我不想将我的模块导入为“bar”我想使用它而没有任何前缀,如

from foo import *

使用它不可能修改其他模块的变量。阅读会奏效!任何的想法?建议?

4 个答案:

答案 0 :(得分:3)

简短回答:不,这是不可能的,你必须使用前缀。

了解from foo import x, y x复制到您的命名空间非常重要。它等同于:

import foo
# COPY TO YOUR NAMESPACE
x = foo.x
y = foo.y
# `from foo import` does NOT leave `foo` in your namespace
def foo

这样,每个模块都会获得xy的本地副本。在其他模块中不会看到更改x,并且您不会看到其他模块所做的更改: - (

要更改变量的核心副本,您必须导入模块本身:import foo并更改foo.x。这样只存在一个副本,每个人都在访问它: - )

[链接的问题还提到了将共享变量放在 builtin 模块中的可能性。别!这将消除阅读它的前缀,但不会删除写入,并且风格非常糟糕。]

保护Python的注释

如果您不想在此处使用foo.前缀,您可能还会反感需要self.前缀来访问对象变量。最重要的是Python的工作方式 - 因为你没有声明变量,所以别无选择,只能使用前缀。

但也有一个好处:在阅读Python代码时,您可以轻松查看每个变量的位置。恕我直言,非常好。

支持证据:在其他语言(如C ++ / Java)中,许多人在所有对象变量名称上都遵循m_前缀等约定来实现类似的效果......

样式备注

  1. 您不需要import foo as bar,只需使用import foo as表单没有做任何新的事情,它只是重命名它,这只是令人困惑 只有“foo”是一个很长的名字才有用;一个特别被接受的案例是当“foo”生活在一些包裹中时,你可以import long.package.foo as foo。{/ p>

  2. from foo import *在程序中被认为是非常糟糕的风格,因为:

    • 阅读代码的人不知道姓名的来源。

    • 它会污染您的命名空间,这可能会在名称来源时导致细微的错误 不同的模块发生冲突。

    显式格式from foo import x, y没问题,但如果您使用模块中的许多名称,则会遇到同样的问题。
    在这种情况下,最好import foo并明确写foo.xfoo.y

  3. 底线:如果有疑问,最简单的import foo

    异常:在交互式解释器上进行实验时, 非常方便使用import *。但请注意,它与reload()不兼容,因此在调试更改代码时请不要使用它。 (要调试您正在编写的模块,最好在IDLE中的模块名称空间 - python -i mymodule.py / F5中启动一个新的解释器

答案 1 :(得分:2)

据我所知,无法从模块导入值,并且导入范围使其可读写。当您在Python中只是import foo时,它会创建一个名为foo的模块对象。获取和设置模块对象的属性将在模块的范围内更改它们。但是当您from foo import something时,导入foo并创建模块对象,但不会返回。相反,Python会复制您在foo之外指定的值,并将它们放在本地范围内。如果您要导入的是不可变类型,如intstr,那么更改它并让更改反映在foo模块中是不可能的。它与此类似:

>>> class N(object):
...   def __init__(self, value):
...     self.value = value
>>> n = N(3)
>>> value = n.value
>>> print value, n.value
3 3
>>> value = 4
>>> print value, n.value
4 3

除了粗暴的黑客,如果你真的想要修改模块的变量,你需要导入模块本身并修改模块上的变量。但一般来说,必须这样做表明设计不好。如果您是相关foo模块的作者,您可能需要查看一些其他更多Pythonic方法来解决您的问题。

答案 2 :(得分:0)

使用import foo from bar,您不会将bar作为变量导入,而是作为常量导入。

答案 3 :(得分:0)

from foo import *(由我Google's style guideOLPC style guide - 你应该看到,因为它最好地解释了为什么这是坏的 - 但不是不幸的是PEP-8。 - 这会产生无法读取的代码。

考虑:

from foo import *
from bar import *
from baz import *

dostuff()

如果您在运行dostuff()时出错,那么您在哪里寻找问题?它可能来自任何进口产品。

对于可读,可维护的代码,请坚持使用from foo import bar。对于可读的,模块化的,可维护的代码,不要破解全局变量 - 扩展bar(通过子类化,如果你不能改变上游源)来公开修改你需要访问的值的方法。