Python: 从包中导入*除了命名空间冲突还有什么缺点吗

3 投票
4 回答
2064 浏览
提问于 2025-04-16 07:48

我正在创建一个类来扩展一个包,但在实例化这个类之前,我不知道需要包的哪个部分。我在自己的代码中小心避免命名冲突,所以,

from package import * 

除了命名冲突之外,这会造成其他问题吗?

是不是更好在类的输入中检查一下,只导入我需要的名称(在运行时)到 __init__ 里呢?

Python 能从一个集合中导入吗?

这个

for name in [namespace,namespace]:
    from package import name

有意义吗?

我希望这个问题看起来不是多余的担忧,我只是对 Python 非常陌生,不想做每个“初学者指南”都说不要做的事情(比如使用 from pkg import *),除非我确定没有其他选择。

欢迎分享想法和建议。

4 个回答

0

你可以这样导入:from PIL import Image, ImageDraw

如果使用from x import *,那么导入的内容会受到__all__这个列表的限制(如果这个列表存在的话)。

如果在运行时需要导入模块,而模块的名字在代码中并不确定或固定,就必须使用__import__,但其实你不需要这样做。

2

当你使用 * 来导入模块时,模块里的所有内容都会直接放到你的命名空间里。这并不总是好事,因为你可能会不小心覆盖掉一些东西,比如:

from time import *
sleep = None

这样会让 time.sleep 函数失去作用...

另一种从模块中获取函数、变量和类的方法是这样说:

from time import sleep

这种方式更好,但通常最好的方法还是直接导入整个模块,然后像这样引用模块:

import time
time.sleep(3)
7

按照顺序来说:

  • 它不会产生其他问题——不过,名字冲突可能比你想象的要麻烦得多。

  • 如果可以的话,尽量延迟导入模块。虽然Python的变量作用域比较简单,但这样做的好处是,如果你需要的功能从来没有被调用,你就不需要导入这个模块。

  • 我不太明白你说的意思。方括号是用来创建列表的,不是集合。你可以在一行中从一个模块导入多个名字——只需用逗号分隔开:

    from awesome_module import spam, ham, eggs, baked_beans
    # awesome_module defines lots of other names, but they aren't pulled in.
    
  • 不,这样做不能达到你想要的效果——name是一个标识符,每次循环时代码都会尝试导入名为name的内容,而不是与name变量所指的字符串对应的名字。

不过,你可以使用__import__函数来实现这种“动态导入”的效果。想了解更多信息,可以查阅文档,但在使用之前一定要确保你有充分的理由。这里会很快进入一些比较高级的用法,通常这些用法并没有看起来那么必要。别想得太复杂。我们可不喜欢那些狡猾的小家伙。

撰写回答