假设你有一个
python包的以下布局
./a
./a/__init__.py
./a/_b.py
你在__init__.py里面
from _b import *
你在_b.py里面
class B(object): pass
如果从交互式提示导入
>>> import a
>>> a.B
<class 'a._b.B'>
>>>
我怎样才能完全隐藏_b的存在?
我试图解决的问题如下:我想要一个导入“隐藏”模块和类的Facade包.从外观(在我的情况下为a)中提供的类保持稳定并保证将来使用.但是,我希望自由地在“引擎盖下”重新定位类,因此隐藏模块.这一切都很好,但是如果一些客户端代码挑选了一个由Facade提供的对象,那么这个pickle数据将引用隐藏模块嵌套,而不是外观嵌套.换句话说,如果我在模块_c.py中重新定位B类,客户端代码将无法解开,因为pickle类指的是a._b.B,它已被移动.如果他们提到a.B,我可以根据需要重新定位B类,而不会破坏腌制数据.
最佳答案 尝试:
B.__module__= 'a'
顺便提一下,您可能想要绝对导入:
from a._b import *
因为没有新的显式点语法的相对导入将消失(see PEP 328).
ETA评论:
I would have to set the module explicitly for every class
是的,我认为没有办法解决这个问题但你至少可以在__init__结束时自动化它:
for value in globals().values():
if inspect.isclass(value) and value.__module__.startswith('a.'):
value.__module__= 'a'
(对于新式类,只有你可以使用isinstance(value,type)而不是inspect.如果模块不必以__main__运行,你可以使用__name__而不是硬编码’a’.)