所有成员包/模块定义?

时间:2010-01-13 10:33:39

标签: python

我如何知道哪些成员模块/包定义了?通过定义我的意思:

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_ATTRIBUTESomeClass

现在我一直在尝试使用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

2 个答案:

答案 0 :(得分:1)

没有办法做到这一点。这是因为简单属性(例如示例中的I_AM_ATTRIBUTE)只是存储在模块字典中的值。当它们被复制到另一个模块时,它们也被放置在该模块的字典中,并且无法分辨哪个是原始位置。您只能告诉提供__module__属性的对象,例如类和函数。

关于野外导入,在您的示例中运行from somemodule import *将导入所有属性,包括ossep。如果包提供__all__变量,则wild import将导入其中包含的名称。否则,它将导入所有不以下划线开头的名称,无论它们最初来自哪个模块。

答案 1 :(得分:1)

“定义”是什么意思?对我来说,定义意味着某些符号是模块公共接口的一部分。这与您尝试使用该术语的方式相匹配,包括在您的示例中,但如果您的某些目的与此定义不一致,则必须澄清有关您的真实内容的问题试图做。这使得成为文档问题

因此,您无法知道模块定义了什么,并且某些导入的内容可能仍然“在该模块中定义”或“定义为该模块的公共接口的一部分”。从私有模块(包括C扩展模块)导入时,通常会发生这种情况。

对于您自己的模块,请使用 __ all __ (可以执行easily)或非公开的非正式下划线前缀(例如_private_var = 42)。这两个约定都被help()识别,并且应该由其他文档生成器使用。