引用python包中的文件

时间:2018-07-22 19:08:54

标签: python path subprocess

我想在PyPI上发布一个python软件包,该软件包具有调用可执行文件的类的方法。

该软件包的结构如下:

/project
    LICENSE
    MANIFEST.in
    README.md
    setup.py
    /package_name
        classA.py
        classB.py
        executableFile
        classC.py

在classA.py方法中,我使用subprocess模块调用可执行文件,如下所示:

subprocess.call('./executableFile', shell=True)

如果我通过pip在virtualenv中安装了软件包,并且使用安装的软件包获得了main.py脚本,如下所示:

from package.classA import classA

obj_instance = classA()
obj_instance.method() #inside this method there is the subprocess.call(...)

程序崩溃,并告诉我未找到可执行文件。我认为是因为subprocess.call(...)在存在main.py而不是package文件夹的文件夹中搜索了executeFile。

如何指定可执行文件的确切路径?

我尝试使用

os.path.dirname(os.path.abspath('executableFile'))

获取包文件夹的名称,但它会向我返回存在main.py的文件夹路径

我该如何解决?

谢谢。

1 个答案:

答案 0 :(得分:0)

setuptools带有pkg_resources框架,用于处理此类情况。

那里有很多文章可供阅读,我不知道有什么好的教程,但是基本思路是:

您将executableFile指定为文件资源。 setuptools找出在安装(或车轮组装)时将其粘贴在哪里。

在运行时,您调用resource_filename以获取到executableFile的路径,然后subprocess.call该路径。

您可能还想使用atexit cleanup_resources函数。

在幕后,pkg_resources将找出所有详细信息。使用--inplace,它将成为您源代码树中的文件;展开安装后,它将是您site-packages中某个位置的文件;如果安装了egg,或者作为py2exe等压缩的站点包的一部分,它将是根据需要提取到缓存目录的文件。但是您不必为此担心。您只需找到一条路径即可。


同时:

  

我认为发生这种情况是因为subprocess.call(...)在main.py文件夹而不是package文件夹中搜索了executableFile。

它搜索当前的工作目录。该可能与目录main.py所在的目录相同,但前提是您的用户通过更改到该目录并运行./main.pypython main.py或相似。

  

我尝试使用

os.path.dirname(os.path.abspath('executableFile'))

那是行不通的,因为abspath也在搜索当前的工作目录,因此,这是获得相同错误路径的更复杂的方法。然后您dirname,然后返回无用的工作目录。

如果您知道从package.classA.pyexecutableFile的相对路径,则可以通过以下方式找到它:

packagedir = os.path.dirname(os.path.abspath(__file__))
execdir = os.path.join(packagedir, '<that relative path>')
execpath = os.path.join(execdir, 'executableFile')

或者,如果您知道来自main.py的相对路径,则可以在main.py内执行相同的操作,并将该路径存储在以后使用的位置(例如,将其传递到{{1} }构造函数。

但这不是理想的解决方案。源树中的相对路径可能与安装后的相对路径不同。如果您的用户以鸡蛋的形式安装软件包,或者将软件包与其他应用程序库的其余部分捆绑在一个zip文件中,那么您只是获得了鸡蛋或zip的路径,因此没有classA可以找到相对于此的任何地方,因为它仅存在于存档中。依此类推。

executableFile的要点是解决所有这些问题,也许是我没有想到的其他问题,以及可能在Python 3.7 / pip 10 / setuptools 40中不存在但将在以下版本中存在的其他问题:您的一位用户从现在起18个月后就开始使用它的Python 3.8 / pip 12 / setuptools 45早就忘记了如何使它一切正常运行...