我面临的情况与这里提出的问题类似:Python Import error on installing ruamel.yaml in custom directory
我知道,我们希望使用某种形式的python环境隔离机制(如virtualenv)来创建可以运行python代码的隔离环境。然而,在我所从事的行业中,我们编写几个Python软件包是很平常的事,这些软件包需要在其他带有自己的Python解释器的现成软件中使用,因此我们受到软件(例如Autodesk Maya)使用的Python版本的限制,并且我们没有使用VielalEnv的灵活性。
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%;
在本例中,软件与Python2.7.14解释器捆绑在一起,我们编写了一个需要ruamel.yaml的包
在第三方软件的python解释器中尝试导入ruamel.yaml时,出现以下错误。
ImportError: No module named ruamel.yaml
即使要从标准python 2.7.14解释器中导入ruamel,我也会遇到同样的问题。
λ 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文件夹成为一个包而不是一个名称空间文件夹,导入错误将消失。似乎在导入带有安装在自定义文件夹中的命名空间的包时存在问题。
我怎样才能解决这个问题?
最佳答案
Namespaces are a honking great idea,但不幸的是,命名空间包的实现有一些问题,ruamel.yaml
安装程序必须解决这些问题。尽管我对.pth
aruamel.yaml
-ed安装程序中的--prefix
文件没有做任何操作,但处理这些文件的方式似乎与处理无前缀安装的方式不同。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/for Maya上是必需的。关于python - 在自定义文件夹中安装ruamel.yaml时ImportError,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49674684/