Python的import语句可以返回types.ModuleType使用导入钩子的子类吗?我想覆盖__getattribute__以在某个模块引用名称不在其中的代码之外显示运行时警告__all__.
我知道如何sys.modules['foo']在导入后进行更换.我想要的是模式匹配的仪器模块,因为它们都是进口,因此进口的代码有机会触发警告.
Python对公开和私密化的想法不以为然.这个想法不是要阻止你的模块用户打字from somemodule import sys; 相反,它是一个文档工具.这种仪器应该通过包含正确的文档来更容易地记录模块的API __all__.它应该可以帮助您避免意外引用sys,somemodule.sys而不是简单地引用import sys.
因为在你编辑它之前我错过了你的问题的重点,我想我会再次打击(留下我原来的答案给后人).
这是一个也不需要导入钩子的替代方案.它可以在逐个模块的基础上轻松使用:包含此代码的模块将具有特殊__getattribute__()行为,而其他模块将像往常一样运行.
class StrictModule(types.ModuleType):
def __getattribute__(self, key):
if key is "__dict__": # fake __dict__ with only visible attributes
return dict((k, v) for k, v in globals().iteritems()
if k.startswith("__") or k in __all__)
if (key.startswith("__") or key in __all__) and key in globals():
return globals()[key]
else:
raise AttributeError("'module' object has no attribute '%s'" % key)
def __setattr__(self, key, value):
globals()[key] = value
sys.modules[__name__] = StrictModule(__name__)
Run Code Online (Sandbox Code Playgroud)
请记住,通过简单地调用常规module类型__getattribute__()(或object类型的类型),这种"限制"很容易解决.我的印象是你试图为你的模块提供某种"私人成员"限制.这几乎没有任何意义.
您甚至不需要导入钩子。只需将对 Python 模块注册表中的对象的引用放在sys.modules所需名称下,importPython 会话中的任何未来语句(甚至在其他模块中)都将导入对该实体的引用。
import types, sys
class MyModuleType(types.ModuleType):
pass
sys.modules["foo"] = MyModuleType("foo")
import foo
print type(foo) # MyModuleType
Run Code Online (Sandbox Code Playgroud)
Python 甚至不关心其中的对象sys.modules实际上是模块还是完全其他类型的对象。你可以在那里扔一个int,但不会给出任何f***。
sys.modules["answer"] = 42
import answer
Run Code Online (Sandbox Code Playgroud)