在python和Java项目之间打包公共资源文件

时间:2019-08-27 15:11:34

标签: python python-3.x setup.py

我有一个已经用Java和Python实现的项目。两种实现都存储在同一存储库中。目前,我的目录结构如下:

mycoolthing/
|-templates/
   |-templateA.txt
   |-templateB.txt
   |-templateC.txt
|-java/
   |-src/
   |-pom.xml
   |-README.md
|-python/
   |-setup.py
   |-README.md
   |-mycoolthing/
     |-mycoolthing.py
   |-tests/
     |-mycoolthing_integration_test.py

Python和Java实现均依赖于templates目录中的模板文件集。理想情况下,我希望这些文件只能放在一个地方,这样我就不必管理两组相同的模板文件。这些模板文件在运行时使用,并且会不时更新,但是读取它们的底层python代码几乎不会改变。

我不确定如何管理python项目之外的资源。如果将templates文件夹移到python目录并将__init.py__添加到目录中,Python允许我加载这些文件。然后,我可以像这样使用importlib_resources通过pkg_resources来引用文件:

import importlib_resources as pkg_resources
text = pkg_resources.read_text('templates', 'templateA.txt')

mycoolthing_integration_test.py文件还需要支持导入mycoolthing软件包,而后者又需要访问templates文件。例如:

import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from mycoolthing import widget

widget是mycoolthing.py中的类,并且像上面的示例一样从pkg_resources中读取模板文件。同样,这仅在templates文件夹位于python目录中并且包含__init.py__时才有效。

我还希望能够通过mycoolthing安装python软件包setup.py install并在此安装中包括所有模板文件。如果模板目录位于python目录中,那么我可以通过package_data中的setup.py属性将模板数据打包在安装中,但是我的目标是使所有模板都位于python外部软件包目录。

通过setup.py管理与其他项目进行共享资源以进行本地开发和打包的python最佳实践是什么。

1 个答案:

答案 0 :(得分:1)

自定义 setuptools 命令可能会帮助...

以下是setup.py的示例,该示例将../templates目录复制到构建的发行版中。这是通过添加自定义copy_templates命令作为install的子命令来完成的。

import distutils.command.install
import os

import setuptools

class copy_templates(setuptools.Command):
    user_options = [
        ('install-dir=', 'd', "directory to install to"),
    ]
    def initialize_options(self):
        self.install_dir = None
    def finalize_options(self):
        self.set_undefined_options(
            'install', ('install_lib', 'install_dir'),
        )
    def run(self):
        self.copy_tree(
            '../templates',
            self.install_dir + 'mycoolthing/templates',
        )

class install(distutils.command.install.install):
    _sub_command = ('copy_templates', None,)
    _sub_commands = distutils.command.install.install.sub_commands
    sub_commands = [_sub_command] + _sub_commands

def setup():
    setuptools.setup(
        # see 'setup.cfg'
        cmdclass={
            'copy_templates': copy_templates,
            'install': install,
        },
    )

if __name__ == '__main__':
    setup()

当然有些细微之处可能可以解决,例如:

  • sdist中的模板将丢失,因为它没有运行install命令。