首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从模块检测“导入模块”vs“从模块导入*”

从模块检测“导入模块”vs“从模块导入*”
EN

Stack Overflow用户
提问于 2013-10-10 23:44:54
回答 2查看 634关注 0票数 0

我希望防止from module import *语句导入模块中的某些名称,以减少名称空间的混乱。(如果设计不好,请告诉我。)

下面是我想要的行为(以osposix为例):

  • import os应该使os.posix可用。
  • from os import *不应使posix可用。
  • 我不在乎from os import posix是否会导致错误。

导入模块module中的代码可以检测它是用import module还是from module import *导入的吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-11 00:13:52

是否可以让导入模块中的代码检测它是与导入模块一起导入的,还是从模块导入*导入的?

是的,至少在CPython。但这不是一件很有用的事情,当然也不能解决你想要解决的问题。当然,正确的答案是使用__all__,就像mgilson展示的那样。

但让我们看看为什么这是错误的答案。

首先,有一种方法可以做到:

代码语言:javascript
复制
import sys
import opcode

f1 = sys._getframe(1)
op = f1.f_code[f1.f_lasti+3]
del f1
if op == opcode.opmap['IMPORT_FROM']:
    print('from me import something')
elif op == opcode.opmap['IMPORT_STAR']:
    print('from me import *')
elif op == opcode.opmap['STORE_NAME']:
    print('import me')

那么,既然你有了这些信息,你能用它做什么呢?在posix的情况下不导入IMPORT_STAR?没有它你的模块还能工作吗?

最重要的是,请记住模块可以--而且经常是--多次导入。如果一个模块用import foo导入您,而另一个模块稍后导入from foo import *,那么您想要发生什么?而且,即使你有答案,你怎么可能这样做,因为你的模块代码只能在第一次运行?它将不得不看到未来,以检测到其他人将在以后的from foo import *

票数 0
EN

Stack Overflow用户

发布于 2013-10-10 23:54:02

我不太明白这个问题。当另一个模块导入时,您可以影响从模块中导入哪些名称。这里有一个简单的test模块:

代码语言:javascript
复制
__all__ = ['foo']

foo = 3
bar = 4

和一个交互式python会议:

代码语言:javascript
复制
>>> import test
>>> test.foo
3
>>> test.bar
4
>>> from test import *
>>> foo
3
>>> bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'bar' is not defined

注意,test.bar是可用的,但bar并不是因为它没有包含在__all__列表中。

最后,值得指出的是,from ... import *的成语确实应该尽量避免。它增加了模拟和测试的难度,它还引入了对象来源的模糊性,除了前面提到的命名空间冲突之外,还使得代码更难读取。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19308062

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档