如何在python安装的软件包中包含文本文件? [英] How to include a text file in a python installed package?
问题描述
我创建了一个看起来像这样的python包:
I have created a python package that looks like this:
/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 __.py 和 module.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')
通过以下方式安装此软件包后:
After intalling this package via:
sudo python setup.py install
然后在命令行中调用程序
And calling the program at the command line
$ command
我收到下面的错误
FileNotFoundError: [Errno 2] No such file or directory: '../file.txt'
如何查看和使用属于已安装软件包的文件,但如何在运行该程序的环境中使用该文件?
How can I see and use a file that belongs to the installed package but I to use it in an environment where I am running that program?
https://github.com/mctrjalloh/project_initializer
推荐答案
因此,经过大量研究,我找到了解决此问题的方法以及它的工作方式.这有点令人困惑,其他所有stackoverflow答案都没有那么解释.我想在这里尝试:
So after a lot research i found the solution to this and how it works also. It's a little bit confusing, none of the other stackoverflow answers were really that explanatory. I want to try it here:
我已经为此目的创建了一个示例项目,以演示和测试解决方案.我提出了两种解决方案:一种使用setup()函数的 data_files 参数,另一种使用我最喜欢的 package_data 参数.
I have made a sample project for that only purpose to demostrate and test the solution. I have come up with two solutions: one using the data_files argument of the setup() function and the other using the package_data argument which i preferred the most.
要在安装后使用它,请运行
To use it after installation run
proj init <some-name>
但简单来说,每种方法都有最重要的模块.
But to be brief there are the most important modules for each method.
使用数据文件 =参数方法:
USING data_files= ARGUMENT METHOD:
项目结构:
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 = 参数方法(我更喜欢)
USING package_data= ARGUMENT METHOD (which i preferred)
项目结构:
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文件中,因为它是主程序包的外部文件.
The reason why i prefer this last method is because you have not to import anything in the setup.py module which could be presumably a bad practice. I guess nothing should be imported in the setup.py file since it is an external file to the main package.
有关这两个参数之间的区别的更详细说明,请查看python文档
For more detailed explanation of what are the differences between the two arguments check out the python docs
这篇关于如何在python安装的软件包中包含文本文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!