我有一个已经用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最佳实践是什么。
答案 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
命令。