【问题标题】:PIP-installed global script throws exception, local copy works flawlesslyPIP 安装的全局脚本抛出异常,本地副本完美运行
【发布时间】:2014-04-07 17:56:44
【问题描述】:

我刚刚在PIP注册了我的新包

python setup.py register
python setup.py sdist upload

我想使用“PIP”将它安装在全局其他机器上(即没有 virtualenv):

sudo pip install standardiser

这一切都很好,因为我有一个文件注册为脚本:

setup(
...
scripts=['standardiser/bin/standardiser.py'],
)

'standariser.py' 现在可在 CLI 命令系统范围内使用。但如果我执行它,我会得到:

mnowotka@candela:~/Documents/ci/curation_interface/trunk/src$ standardiser.py 
Traceback (most recent call last):
  File "/usr/local/bin/standardiser.py", line 32, in <module>
    from standardiser import standardise, SDF
  File "/usr/local/bin/standardiser.py", line 32, in <module>
    from standardiser import standardise, SDF
ImportError: cannot import name standardise

当我显式调用 python 时,我得到了同样的结果:

python /usr/local/bin/standardiser.py

但如果我将它复制到某个本地文件夹:

sudo cp python /usr/local/bin/standardiser.py bla.py

然后从那里运行它:

mnowotka@candela:~$ python bla.py
usage: bla.py [-h] [-V] [-r] infile
bla.py: error: too few arguments

我没有任何ImportErors。我做错了什么?你能帮帮我吗?

我的 setyp.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

__author__ = 'mnowotka'

import sys

try:
    from setuptools import setup
except ImportError:
    from ez_setup import use_setuptools
    use_setuptools()
    from setuptools import setup
setup(
    name='standardiser',
    version='0.1.4',
    author='Francis Atkinson',
    author_email='francis@ebi.ac.uk',
    description='Provides a simple way of standardising molecules as a prelude to e.g. molecular modelling exercises.',
    url='https://www.ebi.ac.uk/chembldb/index.php/ws',
    license='Apache License, Version 2.0',
    scripts=['standardiser/bin/standardiser.py'],
    packages=['standardiser'],
    long_description=open('ReadMe.txt').read(),
    package_data={
        'standardiser': ['bin/*', 'data/*', 'docs/*', 'knime/*', 'test/*',],
        },
    classifiers=['Development Status :: 2 - Pre-Alpha',
                 'Environment :: Console',
                 'Intended Audience :: Science/Research',
                 'License :: OSI Approved :: Apache Software License',
                 'Operating System :: OS Independent',
                 'Programming Language :: Python',
                 'Topic :: Scientific/Engineering :: Chemistry'],
    zip_safe=False,
)

【问题讨论】:

    标签: python virtualenv pip importerror pypi


    【解决方案1】:

    您要求安装一个名为standardiser.py 的脚本;该脚本(至少是您上传到奶酪店的那个)包含以下行:

    from standardiser import standardise, SDF
    

    但这是一个模棱两可的导入;您正在执行的脚本,/usr/local/bin/standardise.py 出现在 sys.path 中,因为主脚本位于那里。它正在导入自身

    无论如何,您都应该使用 setuptools 的 console_scripts 功能。

    修改你的脚本文件

    #! /guess/path/to python
    from standardise import import *
    do_things()
    do_more_things()
    

    from __future__ import absolute_import
    from standardise import import *
    
    def main():
        do_things()
        do_more_things()
    
    if __name__ == '__main__':
        main()
    

    也就是说;

    • 摆脱shebang;在 python 中你永远不需要它!
    • 使用absolute_import 功能获取名为foo.bar.foo 的模块,以便能够导入foo 而不仅仅是foo.bar.foo(您仍然可以将foo.bar.foo 作为from foo.bar import fooimport .foo 导入)。 __future__ 导入必须首先出现在源文件中,在任何其他非注释行(包括其他导入)之前
    • 最重要的是;将导入时的副作用包装在一个函数中,并且仅在这是“主脚本”时才调用这些副作用

    然后将您的setup.py 更改为

    setup(
        scripts=['standardiser/bin/standardiser.py'],
        ...)
    

    setup(
        entry_points={
            'console_scripts': [
                'standardiser=standardiser.bin.standardiser:main']},
        ...)
    

    也就是说:

    • 使用入口点;在这种情况下,setuptools 知道如何在sys.path 上正确获取已安装的包,并且它知道如何连接到正确的python 解释器,即用于运行setup.py 的解释器。当有多个版本的 python 或在 virtualenv 中运行时,这很重要。这就是为什么你永远不需要shebang。
    • 从已安装的可执行文件名称中删除“.py”。对于要在您的可执行路径上的脚本,这不应该存在。

    【讨论】:

    • 精彩的回答,非常有帮助,非常感谢!
    猜你喜欢
    • 2023-03-29
    • 2016-08-24
    • 1970-01-01
    • 2018-04-19
    • 1970-01-01
    • 2019-11-10
    • 1970-01-01
    • 2016-08-05
    • 2012-01-06
    相关资源
    最近更新 更多