我面临的问题与Python Import error on installing ruamel.yaml in custom directory
类似我知道我们会想要使用像virtualenv这样的某种形式的python环境隔离机制来创建我们的python代码可以运行的隔离环境。但是,在我所在的行业中,我们编写几个需要在其他现成软件中使用的python软件包并不常见,因为我们只能使用自己的python解释器。通过软件(例如autodesk maya)使用的python版本,我们不具备使用virtualenv的灵活性。
pip install --install-option="--prefix=\\vm-fs-001\prod\sww\proj\general\python\python-2.7.14" <package_name>
我们使用类似于上述命令的内容将我们编写的代码部署到自定义第三方目录中。我们将环境设置为包含第三方部署文件夹的站点包和脚本。
PYTHONPATH=\\vm-fs-001\prod\sww\proj\general\python\python-2.7.14\Lib\site-packages;%PYTHONPATH%
PATH=\\vm-fs-001\prod\sww\proj\general\python\python-2.7.14\Scripts;%PATH%;
在这种情况下,软件捆绑了python 2.7.14解释器,我们写了一个需要ruamel.yaml的包
尝试在第三方软件的python解释器中导入ruamel.yaml时出现以下错误。
ImportError: No module named ruamel.yaml
即使我从标准的python 2.7.14解释器中导入ruamel,我也得到相同的ImportError。
λ python
Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:25:58) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ruamel.yaml
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named ruamel.yaml
>>> import sys
>>> sys.path
['', '\\\\vm-fs-001\\prod\\sww\\proj\\general\\python\\python-2.7.14\\Lib\\site-packages', 'C:\\windows\\system32\\python27.zip', 'C:\\Python27\\DLLs', 'C:\\Python27\\lib', 'C:\\Python27\\lib\\plat-win', 'C:\\Python27\\lib\\lib-tk', 'C:\\Python27', '\\\\vm-dc-001\\RedirectedFolders$\\nelson.lim\\AppData\\Roaming\\Python\\Python27\\site-packages', 'C:\\Python27\\lib\\site-packages']
>>>
但是,如果我在此处添加__init__.py
:\\vm-fs-001\prod\sww\proj\general\python\python-2.7.14\Lib\site-packages\ruamel\__init__.py
并使ruamel文件夹成为包而不是命名空间文件夹,则导入错误将消失。
似乎导入包含自定义文件夹中安装的命名空间的包有问题。
如何解决此问题?
答案 0 :(得分:0)
Namespaces are a honking great idea,但不幸的是,命名空间包的实现存在一些问题,ruamel.yaml
安装程序必须解决这些问题。虽然我对.pth
安装程序中的ruamel.yaml
文件没有做任何事情--prefix
- ed安装似乎没有像非前缀安装那样处理它们。
ruamel.yaml
安装程序是数据驱动的,setup.py
在许多软件包之间很常见。重写和测试所有这些将花费大量时间而没有任何功能改进,并且到目前为止没有人愿意为此付出代价(并且它可能更好地用于改进命名空间包机制)。
除了完全重新打包ruamel.yaml
之外,如果在ruamel/__init__.py
之前加载了您自己的包时,您应该能够创建from ruamel.yaml import YAML
(假设您的包是取决于ruamel.yaml
)。如果ruamel.yaml
是可选安装,或作为一般解决方法,我建议您创建一个包ruamel_yaml
,在PREFIX/ruamel/__init__.py
中创建该文件(即__init__.py
)文件不存在,然后from ruamel.yaml import *
。
当您使用以下命令进行安装前缀时,这种方法至少适用于基于Linux的安装:
pip install --prefix=/path/to/some/directory ruamel_yaml-0.1-py2.py3-none-any.whl
创建此类包的setup.py
:
from setuptools import setup
import os
from textwrap import dedent
pkg = 'ruamel_yaml'
os.makedirs(pkg)
with open(pkg + '/__init__.py', 'w') as fp:
fp.write(dedent("""\
import sys
import os
fn = __file__.replace('ruamel_yaml', 'ruamel').replace('__init__.pyc', '__init__.py')
if not os.path.exists(fn):
with open(fn, 'w'):
pass
from ruamel.yaml import *
"""))
with open('setup.cfg', 'w') as fp:
fp.write('[bdist_wheel]\nuniversal = 1\n')
setup(name=pkg,
version='0.1',
description='wrapper for --prefix installations of ruamel.yaml',
author='Your Name',
url='http://someurl.com',
author_email='your@email',
license='MIT',
install_requires=['ruamel.yaml'],
packages=[pkg],
zip_safe=False)
使用以下内容创建ruamel_yaml-0.1-py2.py3-none-any.whl
pip install wheel
python setup.py bdist_wheel
如果有必要,生成的__init__.py
也应该实现“使ruamel文件夹成为包而不是命名空间文件夹”的步骤(我不清楚这需要什么),如果在Windows上需要/对于玛雅。