在setup.py build中包含项目根目录中的python文件

在setup.py build中包含项目根目录中的python文件,python,directory,configuration-files,setuptools,setup.py,Python,Directory,Configuration Files,Setuptools,Setup.py,我试图在运行时创建的build/lib目录中包含一个python文件 python setup.py install 特别是,我想包括一个简单的配置文件('definitions.py'),该文件定义一个ROOT_DIR变量,然后子包使用该变量。“definitions.py”文件包含: import os ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) 我的目标是让每个子包('config.py')中的配置文件调用ROOT_DI

我试图在运行时创建的build/lib目录中包含一个python文件

python setup.py install
特别是,我想包括一个简单的配置文件('definitions.py'),该文件定义一个ROOT_DIR变量,然后子包使用该变量。“definitions.py”文件包含:

import os
ROOT_DIR  = os.path.dirname(os.path.abspath(__file__))
我的目标是让每个子包('config.py')中的配置文件调用ROOT_DIR来构建它们自己的绝对路径:

from definitions import ROOT_DIR
PACKAGE_DIR = os.path.join(ROOT_DIR, 'package1/')
这个想法来源于这个答案:
但是,在运行“setup.py install”时,此“definitions.py”文件从未显示在生成目录中。

以下是项目的目录结构:

project | ├── setup.py | ├── definitions.py | ├── package1 | ├── __init__.py | ├── config.py | └── ... | ├── package2 | ├── __init__.py | └── ... └── ... 但是definitions.py不会出现在构建中(我认为这是因为definitions.py不在具有_init__;u.py?)的“包”中)。

2) …使用MANIFEST.in文件,但这也不起作用
(我认为这是因为MANIFEST不适用于.py文件?)

我的问题:

有没有办法将definitions.py包含在构建目录中?或者,有没有更好的办法为多个子包提供对从顶级目录构建的绝对路径的访问?

如果您正在寻找访问已安装模块中非python数据文件的方法,如您链接的问题所示(顶层包中的配置文件,应可在子包中访问),使用
pkg_资源
machine,而不是发明自定义路径解析。示例项目结构:

project
├── setup.py
└── root
    ├── __init__.py
    ├── config.txt
    ├── sub1
    │   └── __init__.py
    └── sub2
        └── __init__.py
setup.py

from setuptools import setup

setup(
    name='myproj',
    ...,
    packages=['root', 'root.sub1', 'root.sub2'],  # or setuptools.find_packages()
    package_data={'root': ['config.txt']}
)
更新: 正如在评论中指出的,现在有了一个backport for(仅在Python 3.7及更高版本中可用),它提供了一个利用
pathlib
的现代资源机制:

# access the filepath
importlib_resources.path('root', 'config.txt')

# access the contents as string
importlib_resources.read_text('root', 'config.txt')

# access the contents as file-like object
importlib_resources.open_binary('root', 'config.txt')
原始答案 使用,您可以从包的任何位置访问
root/config.txt
,而无需执行任何路径解析:

import pkg_resources

# access the filepath:
filepath = pkg_resources.resource_filename('root', 'config.txt')

# access the contents as string:
contents = pkg_resources.resource_string('root', 'config.txt')

# access the contents as file-like object:
contents = pkg_resources.resource_stream('root', 'config.txt')

等等。

相关上下文缺失。1.您正在打包应用程序或库代码吗?2.定义.py中实际上是什么?它基本上只是一个配置文件,还是有逻辑?可能编辑问题以包含内容。编辑以包含上下文说您的目标是让包知道安装位置?请注意,在下面的示例中,
definitions.py
模块包含在已安装的项目目录中,因此它与您在此处尝试的内容完全不同。是的,“目标是让软件包知道安装位置的路径”。很抱歉没有说得更清楚…我目前的理解是build/lib/目录是安装包的地方,这就是为什么我在问题中这样说的原因。我的想法是,访问每个子包的绝对路径最直接的方法是在已安装的包中维护与devel相同的结构opment结构。为什么代码需要知道代码安装在哪里?是为了构建一些数据或资源文件的相对路径吗?如果是这样,这里有更好的选项。这将把
definitions.py
直接放在site packages目录中。不太可能是OP想要的,依我看。它应该在项目som中命名ehow!虽然我同意
py_modules
的用例是在打包单个模块发行版时使用的,但是有许多包出于各种原因定义了顶级模块;
colorama
将其用于常量定义,
pytest
用于定义非私有导入等。我不这么做,但这是可行的le这是否是一个好的实践。鉴于OP现在已编辑成问题的上下文,我必须给出一个坚定的-1。对于包来说,这不是发现安装位置的好方法。嗯,我没有看到。
pkg_参考资料
是setuptools(安装程序)的一部分对于运行时资源管理这样的简单库任务,它有时会有点重/慢。它还创建了对setuptools的不必要的运行时依赖性。对于更现代的方法:
import pkg_resources

# access the filepath:
filepath = pkg_resources.resource_filename('root', 'config.txt')

# access the contents as string:
contents = pkg_resources.resource_string('root', 'config.txt')

# access the contents as file-like object:
contents = pkg_resources.resource_stream('root', 'config.txt')