关于python:Python打包时包含静态文件处理方法

Python打包时蕴含动态文件解决办法

应用场景

  1. 已搭建了PyPI公有库,上传公共库蕴含动态文件,如须要应用sql动态文件初始化数据库。
  2. 打包python包,给其他人应用,但我的项目中蕴含动态文件,如html。

解决步骤

  1. 解决动态文件读取问题
  2. 解决动态文件打包问题

环境

Python3.8
PyCharm 2020

demo我的项目为例

步骤

  1. 创立我的项目
  2. 展现动态文件读取问题
  3. 解决方案
  4. 展现动态文件打包问题
  5. 解决方案

1. 创立我的项目

创立一个demo我的项目(text-setup),目录如下


  • test-setup

    • demo

      • \_\_init\_\_.py
      • demo.py
      • demo.txt

/demo/demo.txt

The text is from demo.txt.

/demo/demo.py

import os


def get_txt():
    """应用原始关上io形式关上"""
    with open('demo.txt', 'r', encoding='utf-8') as f:
        return f.read()


def get_demo_txt():
    """批改获取门路形式,应用io关上"""
    current_dir = os.path.dirname(__file__)
    file_path = os.path.join(current_dir, 'demo.txt')
    with open(file_path, 'r', encoding='utf-8') as f:
        return f.read()


if __name__ == "__main__":
    """类内测试,均无异样"""
    print("get_demo_txt() :", get_demo_txt())
    # get_demo_txt() : The text is from demo.txt.

    print("get_txt() :", get_txt())
    # get_txt() : The text is from demo.txt.

在以后门路下执行demo.py文件没有异样(应用PyCharm间接右键run)

2. 展现动态文件读取问题

在根目录(或其余任意除demo.py文件门路)执行下面的demo.py文件就会报错

$ python demo/demo.py
get_demo_txt() : The text is from demo.txt.
Traceback (most recent call last):
  File "demo/demo.py", line 21, in <module>
    print("get_txt() :", get_txt())  # get_txt() : The text is from demo.txt.
  File "demo/demo.py", line 6, in get_txt
    with open('demo.txt', 'r', encoding='utf-8') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'demo.txt'

显著看出

  • 间接应用相对路径读取动态文件的形式报错
  • 应用os.path.dirname(\_\_file\_\_)获取以后python文件门路并拼接的形式不会报错

3. 解决方案

应用os.path.dirname(\_\_file\_\_)的形式去获取以后python文件门路,再去拼接动态文件的门路

demo中将get_txt()办法删除,持续进行以下打包demo

4. 展现动态文件打包问题

打包,创立打包配置文件
/setup.py

from setuptools import find_packages, setup

setup(
    name='demo',
    version='1.0.0',
    packages=find_packages(),
    zip_sage=False,
)

执行打包命令

$ python setup.py sdist

关上打包信息文件,内容如下
/demo.egg-info/SOURCES.txt

setup.py
demo/__init__.py
demo/demo.py
demo.egg-info/PKG-INFO
demo.egg-info/SOURCES.txt
demo.egg-info/dependency_links.txt
demo.egg-info/top_level.txt

能够看出,demo.txt并不在资源文件中,能够理论试一下,其余我的项目援用这个文件执行获取文件也将报错FileNotFoundError

5. 解决方案

批改打包配置文件
/setup.py

from setuptools import find_packages, setup

setup(
    name='demo',
    version='1.0.0',
    packages=find_packages(),
    zip_sage=False,
    include_package_data=True,  # 打包蕴含动态文件标识
)

减少配置文件
/MANIFEST.in

include demo/demo.txt

最终文件目录


  • test-setup

    • demo

      • \_\_init\_\_.py
      • demo.py
      • demo.txt
    • setup.py
    • MANIFEST.in

再次执行打包命令

$ python setup.py sdist

关上打包信息文件,内容如下
/demo.egg-info/SOURCES.txt

MANIFEST.in
setup.py
demo/__init__.py
demo/demo.py
demo/demo.txt
demo.egg-info/PKG-INFO
demo.egg-info/SOURCES.txt
demo.egg-info/dependency_links.txt
demo.egg-info/top_level.txt

能够看到demo.txt曾经在打包信息当中,援用这个包也不会报错了

参考资料:

Creating a Source Distribution
Flask docs – Make the Project Installable

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理