来自here我了解了如何使用其他模块中的变量。
这一切都很好import foo as bar
但我不想将我的模块导入为“bar”我想使用它而没有任何前缀,如
from foo import *
使用它不可能修改其他模块的变量。阅读会奏效!任何的想法?建议?
答案 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
这样,每个模块都会获得x
和y
的本地副本。在其他模块中不会看到更改x
,并且您不会看到其他模块所做的更改: - (
要更改变量的核心副本,您必须导入模块本身:import foo
并更改foo.x
。这样只存在一个副本,每个人都在访问它: - )
[链接的问题还提到了将共享变量放在 builtin 模块中的可能性。别!这将消除阅读它的前缀,但不会删除写入,并且风格非常糟糕。]
如果您不想在此处使用foo.
前缀,您可能还会反感需要self.
前缀来访问对象变量。最重要的是Python的工作方式 - 因为你没有声明变量,所以别无选择,只能使用前缀。
但也有一个好处:在阅读Python代码时,您可以轻松查看每个变量的位置。恕我直言,非常好。
支持证据:在其他语言(如C ++ / Java)中,许多人在所有对象变量名称上都遵循m_
前缀等约定来实现类似的效果......
您不需要import foo as bar
,只需使用import foo
as
表单没有做任何新的事情,它只是重命名它,这只是令人困惑
只有“foo”是一个很长的名字才有用;一个特别被接受的案例是当“foo”生活在一些包裹中时,你可以import long.package.foo as foo
。{/ p>
from foo import *
在程序中被认为是非常糟糕的风格,因为:
阅读代码的人不知道姓名的来源。
它会污染您的命名空间,这可能会在名称来源时导致细微的错误 不同的模块发生冲突。
显式格式from foo import x, y
没问题,但如果您使用模块中的许多名称,则会遇到同样的问题。
在这种情况下,最好import foo
并明确写foo.x
,foo.y
。
底线:如果有疑问,最简单的import foo
。
异常:在交互式解释器上进行实验时, 非常方便使用import *
。但请注意,它与reload()
不兼容,因此在调试更改代码时请不要使用它。 (要调试您正在编写的模块,最好在IDLE中的模块名称空间 - python -i mymodule.py
/ F5中启动一个新的解释器。
答案 1 :(得分:2)
据我所知,无法从模块导入值,并且导入范围使其可读写。当您在Python中只是import foo
时,它会创建一个名为foo
的模块对象。获取和设置模块对象的属性将在模块的范围内更改它们。但是当您from foo import something
时,导入foo
并创建模块对象,但不会返回。相反,Python会复制您在foo
之外指定的值,并将它们放在本地范围内。如果您要导入的是不可变类型,如int
或str
,那么更改它并让更改反映在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 guide,OLPC style guide - 你应该看到,因为它最好地解释了为什么这是坏的 - 但不是不幸的是PEP-8。 - 这会产生无法读取的代码。
考虑:
from foo import *
from bar import *
from baz import *
dostuff()
如果您在运行dostuff()
时出错,那么您在哪里寻找问题?它可能来自任何进口产品。
对于可读,可维护的代码,请坚持使用from foo import bar
。对于可读的,模块化的,可维护的代码,不要破解全局变量 - 扩展bar
(通过子类化,如果你不能改变上游源)来公开修改你需要访问的值的方法。