我如何知道哪些成员模块/包定义了?通过定义我的意思:
somemodule.py
import os # <-- Not defined in this module
from os.path import sep # <-- Not defined in this module
I_AM_ATTRIBUTE = None # <-- Is defined in this module
class SomeClass(object): # <-- Is defined also...
pass
所以我需要一种某种功能,当被调用时只会产生I_AM_ATTRIBUTE
和SomeClass
。
现在我一直在尝试使用dir(somemodule)
,但我怎么知道somemodule
中定义了哪些?检查__module__
不起作用,因为未在模块和属性(例如os
包或sep
属性)中定义。
显然狂野导入(from somemodule import *
)也无法过滤那些,所以它甚至可能吗?
我能得到的最好的是:
import somemodule
for name in dir(somemodule):
try:
value = getattr(somemodule, name)
except:
pass
else:
if hasattr(value, "__module__"):
if value.__module__ != somemodule.__name__:
continue
if hasattr(value, "__name__"):
if not value.__name__.startswith(__name__):
continue
print "somemodule defines:", name
取出os
,但离开sep
。
答案 0 :(得分:1)
没有办法做到这一点。这是因为简单属性(例如示例中的I_AM_ATTRIBUTE
)只是存储在模块字典中的值。当它们被复制到另一个模块时,它们也被放置在该模块的字典中,并且无法分辨哪个是原始位置。您只能告诉提供__module__
属性的对象,例如类和函数。
关于野外导入,在您的示例中运行from somemodule import *
将导入所有属性,包括os
和sep
。如果包提供__all__
变量,则wild import将导入其中包含的名称。否则,它将导入所有不以下划线开头的名称,无论它们最初来自哪个模块。
答案 1 :(得分:1)
“定义”是什么意思?对我来说,定义意味着某些符号是模块公共接口的一部分。这与您尝试使用该术语的方式相匹配,包括在您的示例中,但如果您的某些目的与此定义不一致,则必须澄清有关您的真实内容的问题试图做。这使得成为文档问题。
因此,您无法知道模块定义了什么,并且某些导入的内容可能仍然“在该模块中定义”或“定义为该模块的公共接口的一部分”。从私有模块(包括C扩展模块)导入时,通常会发生这种情况。
对于您自己的模块,请使用 __ all __ (可以执行easily)或非公开的非正式下划线前缀(例如_private_var = 42
)。这两个约定都被help()识别,并且应该由其他文档生成器使用。