[英]how to import a directory as python module
如果存在目录/home/project/aaa
。 而且我知道这是一个Python包。
因此,我如何仅通过知道其路径来导入该模块。
意味着,我希望代码能够正常工作:
aaa = load_module("/home/project/aaa")
我知道的唯一方法是,将/home/project
添加到sys.path
但这可能会引起一些问题:
如果我将/home/project
添加到sys.path
以及是否在目录/home/project
有dir pytest
。
那么官方的pytest软件包将无法正常工作。
我尝试importlib
了。 但似乎importlib
只能将文件作为模块而不是路径导入。
所以,我尝试一下:
aaa = importlib.import_module("aaa", "/home/project")
要么
aaa = importlib.import_module("aaa", "/home/project/aaa")
他们两个都不工作。
所以,还有其他方法可以做我想要的吗?
哦,我在用Python3.6
于20170628更新
(注意: /home/project/aaa
文件夹中有一个__init__.py
)
我知道的所有解决方案都是从单个文件导入模块。
如果文件夹/home/project/aaa
有bbb.py
文件
然后,将/home/project/aaa
添加到sys.path
或__path__
(无论如何)
import bbb
是可行的,但不能import aaa
我想问的是如何将文件夹(或目录)作为模块导入。
在我的示例中,文件夹aaa
被视为一个模块。
我想使用import aaa
而不是import {SOMETHING IN AAA}
这是完成任务的五种不同方式。
出于以下考虑,我指的是Python 3.5+。
Finder
导入模块时,Python使用查找器 。 如果查找程序知道如何处理特定的请求模块,则它将返回相应的模块规范 ,否则返回None
。 Python已经注册了三个不同的查找器,可以在sys.meta_path
找到sys.meta_path
:
>>> import sys
>>> sys.meta_path
[<class '_frozen_importlib.BuiltinImporter'>, <class '_frozen_importlib.FrozenImporter'>, <class '_frozen_importlib_external.PathFinder'>]
第一个处理内置模块,第二个处理冻结模块(某种“自包含” Python脚本,请参见wiki ),最后一个处理所有可在sys.path
上找到的内容。 因此,如果我们通过添加'/home/project'
修改sys.path
,那么它将是提供相应规范的finder。
无需修改sys.path
我们可以注册使用PathFinder
功能的PathFinder
:
import importlib.machinery
class CustomFinder(importlib.machinery.PathFinder):
_path = ['/home/project']
@classmethod
def find_spec(cls, fullname, path=None, target=None):
return super().find_spec(fullname, cls._path, target)
在这里,我们明确地告诉PathFinder
导入模块时要查看/home/project
。
我们可以按以下方式注册查找程序:
import sys
sys.meta_path.append(CustomFinder)
然后,我们可以导入包aaa
,这将由CustomFinder
找到:
import aaa
有关更多信息,请参阅PEP-302 。
sys.path
我们可以修改sys.path
以便将所需的软件包放在路径上:
import sys
sys.path.append('/home/project')
import aaa
from aaa import whatever
# Optionally remove the added path.
sys.path.pop()
将此目录附加到路径不会由于导入期间执行的搜索顺序而阻止具有相同名称的“现有”(例如,内置软件包)。
__path__
的本地模块 您可以添加包含以下代码的本地模块aaa.py
(实际上您可以将其添加到Python路径上的任何位置):
__path__ = ['/home/project/aaa']
然后,您可以执行import
语句,该语句将引用使用__path__
变量引用的包:
from aaa import whatever
如果要import aaa
,则可以通过在目录层次结构中上一级应用相同的方法来模仿。 使用以下代码添加本地模块project.py
(例如):
__path__ = ['/home/project']
那你可以做
from project import aaa
如果aaa
在路径上,则与import aaa
非常相似(前提是没有其他名为project
模块在路径上具有优先级)。
您可以创建一个指向程序包目录的符号链接。 例如在Unix上:
ln -s /home/project/aaa aaa
然后,可以在import aaa
符号链接的目录中执行此操作,然后通过import aaa
导入软件包。
也可以在程序中通过以下方式创建符号链接
import os
package = '/home/project/aaa'
target = os.path.split(package)[-1] # For example.
if not os.path.exists(target):
# `target_is_directory=True` is needed for Windows platform.
os.symlink(package, target, target_is_directory=True)
# Now import the package.
aaa = __import__(target)
setuptools
安装软件包 您可以添加/home/project/setup.py
脚本,该脚本包含(例如)以下代码:
from setuptools import setup
setup(
name='aaa',
packages=[
'aaa',
# Add any sub-packages that `aaa` contains here.
]
)
然后,您可以通过cd /home && pip install -e project
安装该软件包,然后可以将其轻松导入其他Python文件中:
import aaa
from aaa import whatever
通过使用virtualenv
,可以使已安装的软件包保持干净状态。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.