如何使用setuptools随附的静态文件?

时间:2019-07-11 10:03:24

标签: python setuptools

我想从一个项目在另一个项目中本地安装软件包。我能够安装软件包并导入要调用的函数。该函数加载一个泡菜文件。当我调用该函数时,它失败并显示FileNoutFoundError

我已遵循this answer并使用include_package_data=TrueMANIFEST.in,但这不能解决我的错误。

我有一个简单的项目,其结构如下:

.
├── example_pkg
│   ├── foobar.py
│   ├── __init__.py
│   └── pickle_files
│       └── test.p
├── MANIFEST.in
├── __pycache__
└── setup.py

MANIFEST.in内容:

include example_pkg/pickle_files/*

foobar.py

import os
import pickle


def out():
    with open(os.path.join("pickle_files", "test.p"), "wb") as f:
        pickle.dump({"hello": "world"}, f)


def f_in():
    with open(os.path.join("pickle_files", "test.p"), "rb") as f:
        d = pickle.load(f)
    print(d["hello"])

test.p是通过调用out()创建的。在将软件包安装到另一个项目中以再次创建文件后,我不想调用它,它只是在这里演示文件的来源。

setup.py看起来像这样:

import setuptools

setuptools.setup(
    name="example-pkg-foo",
    version="0.0.1",
    packages=setuptools.find_packages(),
    include_package_data=True,
)

init.py为空。

然后我运行python setup.py sdist,这将创建一个文件夹dist,其中包含文件example-pkg-foo-0.0.1.tar.gz。当我手动检查此tarball时,可以看到example_pkg/pickle_files/test.p存在。

---此行上方的所有内容都是项目A的一部分。下方的所有内容都是项目B的一部分。---

然后我将压缩包复制+粘贴到我的另一个项目(项目B)中并运行pip install example*。然后将该软件包安装在我的项目的(项目B)虚拟环境中。

然后我使用项目B的虚拟环境运行以下脚本:

from example_pkg.foobar import f_in

f_in()

我可以导入包并调用该函数。但是,它失败并显示

Traceback (most recent call last):
  File "/home/madjura/PycharmProjects/package_experiment/foo.py", line 3, in <module>
    f_in()
  File "/home/madjura/PycharmProjects/package_experiment/venv/lib/python3.7/site-packages/example_pkg/foobar.py", line 11, in f_in
    with open(os.path.join("pickle_files", "test.p"), "rb") as f:
FileNotFoundError: [Errno 2] No such file or directory: 'pickle_files/test.p'

检查(项目B的)venv时,我可以看到该文件已包含在安装中:

.
└── site-packages
    ├── example_pkg
    │   ├── foobar.py
    │   ├── __init__.py
    │   ├── pickle_files
    │   │   └── test.p  <------ it is included in the venv
    │   └── __pycache__
    │       ├── foobar.cpython-37.pyc
    │       └── __init__.cpython-37.pyc
    └── example_pkg_foo-0.0.1-py3.7.egg-info
        ├── dependency_links.txt
        ├── installed-files.txt
        ├── PKG-INFO
        ├── SOURCES.txt
        └── top_level.txt

我的Python版本是3.7.3。我想在另一个项目中在本地安装带有pickle文件的软件包,而不创建新的pickle文件。我想使用一个已经存在的。致电FileNotFoundError时如何解决f_in()

1 个答案:

答案 0 :(得分:1)

foobar.py更改为:

import os
import pickle


def out():
    with open(os.path.join(os.path.dirname(__file__), "pickle_files", "test.p"), "wb") as f:
        pickle.dump({"hello": "world"}, f)


def f_in():
    with open(os.path.join(os.path.dirname(__file__), "pickle_files", "test.p"), "rb") as f:
        d = pickle.load(f)
    print(d["hello"])

从其他地方启动它时,解码路径的起点不同。