我在使用Python setuptools时遇到鸡蛋或鸡蛋问题。
我想要实现的是将配置文件与我的pip包(本身完全可以使用data_files
中的setup.py
参数)分发到用户配置文件的OS特定公共位置(例如Linux上的~/.config
。)
我发现OS“特异性”可以使用appdirs
[1] PyPi包来解决。还有我的问题 - 安装我自己的包时不保证安装appdirs
,因为它是我的包的依赖,因此安装在它之后(承诺鸡肉或鸡蛋:))
我的setup.py
包含以下内容:
from setuptools import setup
from appdirs import AppDirs
...
setup(
...
data_files=[
(AppDirs(name, author).user_config_dir, ['config/myconfig'])
],
...
)
这可以在不编写我自己的setuptools版本的情况下解决(暗示意图;))?
答案 0 :(得分:2)
正如我在评论中提到的,我建议将您的文件的通用副本与您的包一起分发,然后在运行时将其复制到用户的配置目录(如果它不存在)。
这应该不是很难并涉及:
使用setuptools
的{{1}}(而不是package_data
)。这会将文件放置在运行时使用data_files
在特定操作系统的“正确”位置
程序运行时,使用pkg_resources
查找特定于用户的本地安装文件。
如果不存在,请使用appdirs
查找文件并将其复制到pkg_resources
虽然我还没有这样做,但是这个过程应该适用于多个操作系统和环境,并且在开发过程中也可以使用appdirs
。
pkg_resources
在setup.py中,您应确保使用setup.py
包含数据包的数据文件:
package_data
setup(
# ...
data_files={
"my_package": [ "my_package.conf.dist"
}
# ...
)
我希望这会清除import os.path
import pkg_resources
import appdirs
def main():
"""Your app's main function"""
config = get_config()
# ...
# ...
def get_config():
"""Read configuration file and return its contents
"""
cfg_dir = appdirs.user_config_dir('MyApplication')
cfg_file = os.path.join(cfg_dir, 'my_application.conf')
if not os.path.isfile(cfg_file):
create_user_config(cfg_file)
with open(cfg_file) as f:
data = f.read()
# ... probably parse the file contents here ...
return data
def create_user_config(cfg_file):
"""Create the user's config file
Note: you can replace the copying of file contents using shutil.copyfile
"""
source = pkg_resources.resource_stream(__name__, 'my_package.conf.dist')
with open(cfg_file, 'w') as dest:
dest.writelines(source)
和pkg_resources
的使用情况。