gpt4 book ai didi

python - 如何在 python 安装包中包含文本文件?

转载 作者:太空宇宙 更新时间:2023-11-04 06:40:31 25 4
gpt4 key购买 nike

我创建了一个如下所示的 python 包:

/command
/command
module.py
__main__.py
README.md
setup.py
file.txt

安装我运行:

sudo python setup.py install

现在当我打电话

$ command

它显示了这个错误:

FileNotFoundError: [Errno 2] No such file or directory: '../file.txt'

大概有模块setup.py__main__.pymodule.py

的内容

setup.py

import setuptools

setuptools.setup(
name='command',
...
entry_points={
'console_scripts': [
'command = command.__main__:main'
]
}
)

__main__.py

from . import module

def main():
module.run('arg')

module.py

import shutil

# copy file.txt from command project into the directory where it is running
def run(arg):
shutil.copyfile('../file.txt', './file.txt')

通过以下方式安装此包后:

sudo python setup.py install

并在命令行调用程序

$ command

我得到以下错误

FileNotFoundError: [Errno 2] No such file or directory: '../file.txt'

如何查看和使用属于已安装包的文件,但我要在运行该程序的环境中使用它?

编辑:

This a simplification of the problem you can download and test:

https://github.com/mctrjalloh/project_initializer

最佳答案

经过大量研究,我找到了解决这个问题的方法以及它的工作原理。这有点令人困惑,其他 stackoverflow 答案都没有真正的解释。我想在这里试试:

我制作了一个示例项目,仅用于演示和测试解决方案。我想出了两种解决方案:一种使用 setup() 函数的 data_files 参数,另一种使用我最喜欢的 package_data 参数。

Here is the link to the github repo you can download and test

安装运行后使用

proj init <some-name>

但简而言之,每种方法都有最重要的模块。

使用 data_files= 参数方法:

项目结构:

project_initializer
project_initializer
__init__.py
__main__.py
init.py
README.md
setup.py

setup.py

import setuptools
import os
import sys


PROJECT_NAME = "project_initializer"
DATA_DIR = os.path.join(
sys.prefix, "local/lib/python3.6/dist-packages", PROJECT_NAME)


setuptools.setup(
name='project_initializer',
version='0.1.0',
packages=setuptools.find_packages(),
install_requires=[
'docopt'
],
data_files=[ # is the important part
(DATA_DIR, [
"README.md",
".gitignore"
])
],
entry_points={
'console_scripts': [
'proj = project_initializer.__main__:main'
]
}
)

init.py

import subprocess
import os
import shutil
import sys

"""Create a new project and initialize it with a .gitignore file
@params project: name of a project to be initialized
effects:
/project
README.md
README.md in the created project directory must be the same as the README.md in THIS directory
"""

PROJECT_NAME = "project_initializer"
DATA_DIR = os.path.join(
sys.prefix, "local/lib/python3.6/dist-packages", PROJECT_NAME)


def run(project):
os.mkdir(project)
shutil.copyfile(os.path.join(DATA_DIR, "README.md"),
f"{project}/README.md") # problem solved


if __name__ == '__main__':
run("hello-world")

使用 package_data= ARGUMENT METHOD(我更喜欢)

项目结构:

project_initializer
project_initializer
data/
README.md # the file we want to copy
__init__.py
__main__.py
init.py
README.md
setup.py

setup.py

import setuptools


setuptools.setup(
name='project_initializer',
version='0.1.0',
packages=setuptools.find_packages(),
package_dir={'project_initializer': 'project_initializer'}, # are the ...
package_data={'project_initializer': [ # ... important parameters
'data/README.md', 'data/.gitignore']},
install_requires=[
'docopt'
],
entry_points={
'console_scripts': [
'proj = project_initializer.__main__:main'
]
}
)

init.py

import subprocess
import os
import shutil
import sys

PROJECT_DIR = os.path.dirname(__file__)

"""Create a new project and initialize it with a .gitignore file
@params project: name of a project to be initialized
effects:
/project
.gitignore
.gitignore in the created project directory must be the same as the gitignore in THIS directory
"""


def run(project):
os.mkdir(project)
shutil.copyfile(os.path.join(PROJECT_DIR, 'data/README.md'),
f"{project}/README.md") # problem solved


if __name__ == '__main__':
run("hello-world")

我更喜欢最后一种方法的原因是你不必在 setup.py 模块中导入任何东西,这可能是一种不好的做法。我想 setup.py 文件中不应导入任何内容,因为它是主包的外部文件。

要更详细地解释这两个参数之间的区别,请查看 python 文档

Using data_files= argument

Using package_data= argument

关于python - 如何在 python 安装包中包含文本文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53454049/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com