我有一个非常简单的装饰器函数,用于通过模块的__all__
属性公开模块中定义的函数。因为我将它用于包中的多个模块,所以我在包__init__.py
中定义了它。
因为我不能在定义中使用__all__
,因为它会引用__all__
模块的__init__.py
(或者更确切地说是包),我现在正在这样做:
def expose ( fn ):
fn.__globals__['__all__'].append( fn.__name__ )
这似乎完全正常。但是我不确定使用__global__
属性是否是理想的方法,特别是因为该属性似乎没有文档(至少我在文档中找不到任何关于它的内容)。
使用__globals__
是否合适,或者是否有更简单,更健壮的方法来实现这一目标?
为了澄清,我不一定需要访问模块的__all__
属性。我可以轻松地使用不同的名称,最终得到相同的问题。我只是使用__all__
,因为它保存模块中所有公开对象的目的与我的意图相符。但与此同时,我也可以将它命名为exposedFunctions
或其他什么。所以问题更多的是如何访问模块的全局属性。
答案 0 :(得分:2)
你可能会喜欢Thomas Rachel的AllList
装饰者:
class AllList(list):
"""list which can be called in order to be used as a __all__-adding decorator"""
def __call__(self, obj):
"""for decorators"""
self.append(obj.__name__)
return obj
从之前导入它,并在模块的顶部有
__all__ = whereever.AllList()
然后在你的模块中它看起来像
@__all__
def some_func():
...
@__all__
def another_func():
...
并且无需担心全局变量。
<强>更新强>
如果你真的想担心全局变量,请看一下Use a class in the context of a different module - 但它并不漂亮。