Python 打包:数据文件已正确放入 tar.gz 文件中,但未安装到虚拟环境中

Posted

技术标签:

【中文标题】Python 打包:数据文件已正确放入 tar.gz 文件中,但未安装到虚拟环境中【英文标题】:Python Packaging: Data files are put properly in tar.gz file but are not installed to virtual environment 【发布时间】:2012-10-29 17:36:29 【问题描述】:

我无法将项目package_fiddler 正确安装到我的虚拟环境中。

我发现MANIFEST.in负责将非.py文件放入Package_fiddler-0.0.0.tar.gz,这是在执行python setup.py sdist时生成的。

然后我做了:

(virt_envir)$ pip install dist/Package_fiddler-0.0.0.tar.gz

但这并没有将数据文件和包安装到/home/username/.virtualenvs/virt_envir/local/lib/python2.7/site-packages

我尝试了许多设置参数package_datainclude_package_datadata_files 的配置,但我似乎每次都使用了错误的配置。

package_data 和/或include_package_data 和/或data_files 的哪种配置可以正确地将package_fiddler 安装到我的虚拟环境中?

项目树

.
├── MANIFEST.in
├── package_fiddler
│   ├── data
│   │   ├── example.html
│   │   └── stylesheets
│   │       └── example.css
│   └── __init__.py
├── README.rst
└── setup.py

setup.py

from setuptools import setup


setup(
    name='Package_fiddler',
    entry_points=
    'console_scripts': ['package_fiddler = package_fiddler:main', ],,
    long_description=open('README.rst').read(),
    packages=['package_fiddler',])

MANIFEST.in

include README.rst
recursive-include package_fiddler/data *

我尝试过 setup.py 的哪些配置(上面有代码库)?

配置1

添加:

package_data="": ['package_fiddler/data/*',]

配置2

添加:

package_data="": ['*.html', '*.css', '*.rst']

配置3

添加:

include_package_data=True

配置4

添加:

package_data="": ['package_fiddler/data',]

删除:

packages=['package_fiddler',]

配置5(克里斯的建议)

添加:

package_data="data": ['package_fiddler/data',]

删除:

packages=['package_fiddler',]

配置6

添加:

package_data="": ['package_fiddler/data/*',]

删除:

packages=['package_fiddler',]

这些配置都导致/home/username/.virtualenvs/virt_envir/local/lib/python2.7/site-packages 上根本没有安装任何文件。

编辑

仓富敏夫的注意事项: 在我原来的帖子中,为了清楚起见,我使用了最简单的树结构,但实际上我的树看起来更像下面的树。对于那棵树,奇怪的是,如果我只在stylesheets 中放一个__init__.py,那么texts 文件夹中的所有数据文件也都安装正确!!!这让我很困惑。

树 2(这会以某种方式正确安装所有数据文件!!)

.
├── MANIFEST.in
├── package_fiddler
│   │── stylesheets
|   |     ├── __init__.py
|   |     ├── example.css  
|   |     └── other
|   |          └── example2.css
|   |__ texts
|   |     ├── example.txt  
|   |     └── other
|   |          └── example2.txt
│   └── __init__.py
├── README.rst
└── setup.py

【问题讨论】:

【参考方案1】:

找到了适合我的解决方案here。

使用setuptools==2.0.2 我做了:

setuptools.setup(
    ...
    packages=setuptools.find_packages(),
    include_package_data=True,  # use MANIFEST.in during install
    ...
)

【讨论】:

不错!该功能几乎解决了所有问题,我很惊讶这是我第一次听说它。我认为这应该是公认的答案,而不是__init__.py hack。 这确实是正确的答案,这解决了我所有的问题。 __init__.py hack 对我不起作用,因为我已经在树中的任何地方放置了 init 文件!此外,init 技巧对于非 python 数据文件也无济于事。 这行得通。注意:答案中没有明确提及,但在 setup.py 中删除 package_data=... 并从数据子目录中删除 __init__.py 文件:此方法不需要它们。 -- 只需使用 MANIFEST.in 并设置 include_package_data=True。我经历的另一件事是来自 MANIFEST.in 的数据文件需要位于 python 代码子树(至少一个检测到的包)下,否则它们不会被安装。 另外请注意,如果您打算稍后在运行时使用os.path.dirname(__file__) 路径算法从 MANIFEST.in 加载文件,添加 zip_safe=False 可能有助于确保正确性(省略 zip_false 将使 bdist_egg 推断它是否通过文件检查安全)docs。见other answer。【参考方案2】:

我个人不喜欢 setuptools 在概念上和实现上混合代码和数据的方式。我认为正是这种实现让你陷入了困境。为了让 setuptools 找到和使用 package_data,它需要将数据驻留在 python 包中。 python包可以是一个目录,但目录中需要有一个__init__.py文件。所以看起来你需要以下(空的很好)文件:

./package_fiddler/data/__init__.py
./package_fiddler/data/stylesheets/__init__.py

【讨论】:

我之前也遇到过类似的问题,确实需要init.py。 ***.com/questions/3760970 我同意。奇怪的是,嵌套数据文件中只需要一个__init__.py 文件即可在我的帖子的编辑部分中正确安装带有tree2 的项目! __init__.py 用于使目录可作为模块导入——这对于数据目录来说不是必需的。见my answer here。 @Leo 是的,__init__.py 很糟糕,但是package_datadistutils 的功能,setuptools 忽略了它。此外,package_data 在运送sdists 时不起作用。一般来说,python 中的包装是可怕的;人们更喜欢 hacky __init__.py 解决方案而不是不一致的 package_data 解决方案,请让他们。 直到今天我仍然遇到 package_data 未包含在生成的车轮包中的问题。我必须将 manifest.in 与正确的包含一起使用,我必须将空的 __init__.py 文件放在数据文件夹中,并且我需要另外使用 packages 参数显式添加数据文件夹进行设置。否则,我只使用了 ext_modules。圣诞节后的噩梦。【参考方案3】:

在“setup.py”中包含包数据的最简单方法如下:

package_data = '<package name>': ['<path to data file within package dir>']

所以在你的例子中:

package_data = 'package_fiddler': ['data/*', 'data/stylesheets/*']

package_data 是一个字典,其中的键是安装程序中包含的包的名称。这些键下的值应该是包目录中特定文件路径或全局/通配符的列表。

您还需要包含标志:

zip_safe=False

如果您希望能够解析数据的文件系统路径,请在setup(...) 中。否则,您可以使用pkg_resources 执行此操作:http://peak.telecommunity.com/DevCenter/PythonEggs#accessing-package-resources

您绝对不需要“数据”目录中的__init__.py 文件 - 此目录不是模块,也不打算导入。

【讨论】:

是的,这行得通。但是您必须复制MANIFEST.insetup.py 中的路径并保持同步。 这,这,这!最糟糕的是,文档让人们相信 MANIFEST.in 是 NOT 需要的,而我还没有找到一种方法让它在没有它的情况下工作。 :(【参考方案4】:

使用

package_data="data": ['package_fiddler/data',]

而不是

packages=['package_fiddler',]

【讨论】:

它没有改变任何东西。当我重新打包后 pip install 项目时,在虚拟环境中仍然找不到任何东西。 您在setup.py 中使用了from setuptools import setup 还是from distutils.core import setup【参考方案5】:

这对我有用。希望能帮助到你。

package_data=
    "package_fiddler": [
        '\*.\*',
        '\*/\*.\*',
        '\*/\*/\*.\*',
    ],
,

【讨论】:

我还以为是一种ASCII图形=)

以上是关于Python 打包:数据文件已正确放入 tar.gz 文件中,但未安装到虚拟环境中的主要内容,如果未能解决你的问题,请参考以下文章

python程序打包,来源于知乎(已验证)

run build打包之后axios能连上,websocket连不上问题已解决

run build打包之后axios能连上,websocket连不上问题已解决

run build打包之后axios能连上,websocket连不上问题已解决

run build打包之后axios能连上,websocket连不上问题已解决

超良心!18张 Python 数据科学速查表,已打包可下载!