【问题标题】:How to create and load internal data in Python package如何在 Python 包中创建和加载内部数据
【发布时间】:2025-11-21 18:15:02
【问题描述】:

我正在开发一个Python包,Python包的实现依赖于一些研究成果。我将我的研究结果保存在 Python 字典中。我有两个问题:

  1. 如何将此字典作为内部数据保存在我的包中?
  2. 在包中编写函数时,如何加载这个内部数据?

我查看了this,但仍然不知道如何从头开始保存包内部数据。它也没有显示如何加载保存的内部数据。 R中有devtools::use_data之类的东西吗?

【问题讨论】:

  • 保存到文件,加载到模块中,导入模块。字典很容易序列化为 json - docs.python.org/3/library/json.html。或者你可以pickle它。 docs.python.org/3/library/persistence.html#data-persistence.
  • 我想我应该问一下research result 是动态的还是静态的? result 在包/模块执行期间是否更改? result 是否在执行开始时确定一次然后从那时起使用? result 是否永远不会更改,您只需要在执行开始时加载它吗?
  • 您链接到 2.6 版文档。如果可能,您应该切换到 Python 3.7+。
  • @wwii 感谢您的回复,链接已更改。是的,research result 已确定。 result 在包/模块执行期间不会改变。我只需要在执行开始时加载它。
  • 所以你问如何在执行开始时加载它并使其可用?你不是在问如何打包分发?

标签: python python-3.x module package python-internals


【解决方案1】:

这是我通常使用 pip 为标准 python3 分发所做的(它反映了位 R 数据分发)。

  1. 在您的代码目录中为数据创建一个文件夹,我们将其命名为“my_data”。 在这里你可以放任何你想要的东西:csv、json、pickle... 但请注意,pickle 在加载到 python 版本时可能会出现一些问题,而不是用于创建它的版本。 此外,pickle 还存在一些安全性问题,因此如果您要分发软件包,请选择其他格式。

然后,如果您的包被称为“my_data_pack”,您将拥有以下文件夹结构:

.
├── my_data_pack
│   ├── __init__.py
│   └── my_data
│       └── data_file.txt
└── setup.py

  1. 在您的setup.py 文件的setup 函数中包含此行:
from setuptools import setup, find_packages

setup(
    name='my_data_pack',
    packages=find_packages(),
    package_data={'my_data_pack': ['my_data/*']}
)

这将使数据在构建 pip 时包含在 tar.gz 分发文件中。 根据您的包结构,您可能需要将行更改为 package_data={'mypkg': ['my_data/*.dat']}, 正如您提到的链接中所示。

  1. 最后一个棘手的事情是如何使包中的模块在安装时找到数据集。 这个想法是首先在安装包的目录中找到数据文件,然后将数据加载到您的模块中。 要定位数据文件,您可以使用ospkg_resources

要使用os,请在您的__init__.py 文件(或您正在使用的任何其他子模块)中包含这些行:

import os

location = os.path.dirname(os.path.realpath(__file__))
my_file = os.path.join(location, 'my_data', 'data_file.txt')

with open(my_file) as fin:
    my_data_object = fin.readlines()

如果您更喜欢使用pkg_resources,也可以使用这些:

import pkg_resources

my_file = pkg_resources.resource_filename('my_data_pack', 'my_data/data_file.txt')

with open(my_file2) as fin:
    my_data_object = fin.readlines()

更改readlines 部分以读取您自己的数据格式。这就是包代码所需要的全部内容。

  1. 为了制作我运行的库分发:
python3 setup.py sdist

这将创建一个名为“dist”的新目录,其中包含 tar.gz 文件。 然后你可以将你的包安装为

pip3 install dist/my_data_pack-0.0.0.tar.gz

要访问您的 python 会话中的数据,您将执行以下操作:

import my_data_pack
print(my_data_pack.my_data_object)

在旧的 R 时代(devtools 之前:),您可以使用带有选项 packagesystem.file 函数 找到已安装库的位置,然后加载数据...类似于 python os.path.realpah

【讨论】:

【解决方案2】:

Python 3.4 将pathlib 模块添加到标准库中,这使得文件和目录位置的处理更加优雅。

要获取安装包的目录,可以将其包含在__init__.py中:

from pathlib import Path
PACKAGEDIR = Path(__file__).parent.absolute()

要获取包目录内文件的路径,可以如下构造路径:

my_file = PACKAGEDIR / 'my_data' / 'data_file.txt'

【讨论】:

    最近更新 更多