Jas*_*ker 53 python module path
我从来没有注意到__path__今天之前在我的某些软件包上定义的属性.根据文件:
包支持另一个特殊属性
__path__.这被初始化为一个列表,其中包含在__init__.py执行该文件中的代码之前保存包的目录的名称.这个变量可以修改; 这样做会影响将来对包中包含的模块和子包的搜索.虽然通常不需要此功能,但它可用于扩展程序包中的模块集.
有人可以向我解释这究竟是什么意思以及为什么我会想要使用它?
Syn*_*tic 32
如果更改__path__,则可以强制解释器在属于该包的模块的不同目录中查找.
这将允许您根据运行时条件加载相同模块的不同版本.如果要在不同平台上使用相同功能的不同实现,则可以执行此操作.
Ian*_*ing 32
这通常与pkgutil一起使用,以便在磁盘上布置包.例如,zope.interface和zope.schema是单独的发行版(zope是"命名空间包").你可能安装了zope.interface /usr/lib/python2.6/site-packages/zope/interface/,而你在本地使用zope.schema /home/me/src/myproject/lib/python2.6/site-packages/zope/schema.
如果你放入pkgutil.extend_path(__path__, __name__),/usr/lib/python2.6/site-packages/zope/__init__.py那么zope.interface和zope.schema都是可导入的,因为pkgutil将__path__改为['/usr/lib/python2.6/site-packages/zope', '/home/me/src/myproject/lib/python2.6/site-packages/zope'].
pkg_resources.declare_namespace(Setuptools的一部分)很像,pkgutil.extend_path但更了解路径上的拉链.
手动更改__path__是不常见的,可能不是必需的,但在调试命名空间包的导入问题时查看变量很有用.
你也可以用__path__monkeypatching,例如,我有时通过创建一个distutils/__init__.py早期的文件monkeypatched distutils sys.path:
import os
stdlib_dir = os.path.dirname(os.__file__)
real_distutils_path = os.path.join(stdlib_dir, 'distutils')
__path__.append(real_distutils_path)
execfile(os.path.join(real_distutils_path, '__init__.py'))
# and then apply some monkeypatching here...
Run Code Online (Sandbox Code Playgroud)
除了根据运行条件选择不同版本的模块,如Syntactic所说,此功能还允许您将包拆分为多个部分/下载/安装,同时保持单个逻辑包的外观.
考虑以下.
mypkg和_mypkg_foo._mypkg_foo包含可选模块mypkg,foo.py.mypkg不包含foo.py.mypkg的__init__.py可以做一些事情,像这样:
try:
import _mypkg_foo
__path__.append(os.path.abspath(os.path.dirname(_mypkg_foo.__file__)))
import mypkg.foo
except ImportError:
pass
Run Code Online (Sandbox Code Playgroud)
如果有人安装了包_mypkg_foo,那么mypkg.foo他们就可以使用.如果他们没有,它就不存在.
我遇到的一个特殊情况是,当一个包变得足够大时,我想将其部分拆分到子目录中,而不必更改引用它的任何代码。
例如,我有一个名为的包views,它收集了许多支持实用程序函数,这些函数与该包的主要顶级用途混淆了。我能够将这些支持功能移动到子目录中utils,并将以下行添加到__init__.py包中views:
__path__.append(os.path.join(os.path.dirname(__file__), "utils"))
Run Code Online (Sandbox Code Playgroud)
也有了这个改变views/__init_.py,我可以使用新的文件结构运行软件的其余部分,而无需对文件进行任何进一步的更改。
import(我尝试对文件中的语句执行类似的操作views/__init__.py,但是通过导入子包模块仍然不可见view- 我不完全确定我是否遗漏了其中的某些内容;欢迎发表评论!)
(此响应基于Python 2.7安装)
| 归档时间: |
|
| 查看次数: |
22872 次 |
| 最近记录: |