Python CLI and Import Module



我想弄清楚如何建立一个python项目;作为CLI命令和导入对象。这可能有一个简单的答案,但我不太熟悉技术术语,所以我不太确定我需要研究什么。

我想要的:mytool是一个"巨蟒";(模块/包?)我可以运行pip install -e /home/user/project/mytool/(或者任何需要的东西)那么我可以用以下两种方式使用它:

  • 使用mytool作为CLI命令:
CLI usage: mytool string_input
CLI output: result_string
  • 在不同的python脚本中导入mytool并在那里使用:
In other script usage:
import mytool
result_string = mytool.process_string(string_input)

这是我的设置:

$ tree ./mytool/
./mytool/
├── __init__.py
├── setup.py
├── mytool
│   ├── mytool_helper.py
│   └── mytool.py
├── mytool.egg-info
│   ├── dependency_links.txt
│   ├── entry_points.txt
│   ├── PKG-INFO
│   ├── requires.txt
│   ├── SOURCES.txt
│   └── top_level.txt
├── mytool_helper.py
└── mytool.py
2 directories, 12 files

我知道我不需要mytool.py和mytool_helper.py在两个文件夹中,但这已经是我的粗略尝试得到一些工作,在修剪之前。我试着把它和其他一些python的东西结合起来,但是我想我在这一点上把自己弄糊涂了。

我也读过__init__.py可以是空的,但它可能是我正在寻找的,这是__init__.py的内容:

from mytool.mytool import *

setup.py内容:

"""
The setup module(?) for mytool
"""
# To use a consistent encoding
from os import path
# Always prefer setuptools over distutils
from setuptools import setup, find_packages
version = '0.0.2'
here = path.abspath(path.dirname(__file__))
setup(
name='mytool',
version=version,
description='Do stuff with a string',

packages=find_packages(),
py_modules=['mytool'],
classifiers=[
'Programming Language :: Python :: 3.10'
],
install_requires=[
'argparse',
'pyyaml'
],
extras_require={
},
entry_points={
'console_scripts': [
'mytool=mytool.mytool:main'
]
}
)

mytool.py的内容(简化):

import json
import argparse
from mytool.mytool_helper import HelperClass
# various string manipulation functions
#...
def process_string(in_string):
result = HelperClass.parse_string(in_string)
#  Do stuff with string
return result.to_string()

def main():
# This just gets the input via argparse
input_string = _get_input_string()
result_string = process_string(input_string)
print(json.dumps(result_string, indent=4, default=str))

if __name__ == "__main__":
main()

当前行为为:pip install -e /home/user/project/mytool/

  • CLI:mytool string_to_process
  • 在脚本中:
from mytool import mytool
result = mytool.process_string("string_to_process")

我如何修复和清洁我的项目,这样我就可以在下面使用,同时仍然具有CLI功能?

import mytool
result = mytool.process_string("string_to_process")

我不直接需要帮助器"importable"。

终于找到了一个问题,使我找到了解决方案,但我仍然欢迎反馈和评论!

这个问题:https://softwareengineering.stackexchange.com/q/243044(他们问哪个更受欢迎)询问单个python文件分布,其中您有一个文件foo.py,其中有一个内部的东西(函数,类等)称为useful_thing

他们提供了两种文件架构,所以可以使用from foo import useful_thing(这也将允许以下功能:

import foo
foo.useful_thing

)他们在问题中提供的文件结构是:

$ tree -a ./foo_folder/
./foo_folder/
├── setup.py
├── README.rst
├── ...etc...
└── foo.py
0 directories, 4 files

$ tree -a ./foo_folder/
./foo_folder/
├── setup.py
├── README.rst
├── ...etc...
└── foo
├── module.py
└── __init__.py
2 directories, 4 files

其中useful_thingmodule.py中定义,__init__.py的内容为:

from foo.module import useful_thing

这个问题和答案:https://softwareengineering.stackexchange.com/a/243045(意思是:选择适合你的。)提供两个示例包,它们只是一个模块的发行版。特别是https://pypi.org/project/six/,我使用该结构使我的工具既可以作为CLI工具又可以导入。

这是最后的结果:

$ tree ./mytool/
./mytool/
├── mytool.egg-info
│   ├── dependency_links.txt
│   ├── entry_points.txt
│   ├── PKG-INFO
│   ├── requires.txt
│   ├── SOURCES.txt
│   └── top_level.txt
├── mytool_helper.py
├── mytool.py
└── setup.py
1 directory, 9 files

setup.py:

"""
The setup module for mytool
"""
# To use a consistent encoding
from os import path
# Always prefer setuptools over distutils
from setuptools import setup, find_packages
import mytool # NOTE: this is importing the file
version = '0.0.2'
here = path.abspath(path.dirname(__file__)) # NOTE: This is leftover, I should probably prune
setup(
name='mytool',
version=version,
description='Do stuff with a string',

#packages=find_packages(), # NOTE: I commented this because I don't think it's technically a "package" anymore just a moduel
py_modules=['mytool'],
classifiers=[
'Programming Language :: Python :: 3'
],
install_requires=[
'argparse',
'pyyaml'
],
extras_require={
},
entry_points={
'console_scripts': [
'mytool=mytool:main'  # NOTE: have to change this here because the file structure is different
]
}
)

mytool.py的内容(简化):

import json
import argparse
from mytool_helper import HelperClass # NOTE:You just import the helper file/module directly here rather than as a module as part of a package.
# various string manipulation functions
#...
def process_string(in_string):
result = HelperClass.parse_string(in_string)
#  Do stuff with string
return result.to_string()

def main():
# This just gets the input via argparse
input_string = _get_input_string()
result_string = process_string(input_string)
print(json.dumps(result_string, indent=4, default=str))

if __name__ == "__main__":
main()

允许使用pip以可编辑的方式安装:pip install -e /home/user/project/mytool/

  • 命令行用法:mytool string_to_process
  • 在脚本
  • :
import mytool
result = mytool.process_string("string_to_process")

我可能仍然在这里混淆术语,但这应该有助于了解结构和文件内容的人。我可能还应该解释其他部分,或者提供一些链接,比如如何使工具的CLI部分(https://setuptools.pypa.io/en/latest/userguide/entry_point.html)

最新更新