python - 在 Python 中使用入口点时区分导入的包和在 CLI 中运行的包
问题描述
我有一个最常用作 CLI 工具的 python 包,但有时我出于自己的目的将它作为库运行。(例如把它变成一个网络应用程序或进行单元测试)
例如,sys.exit(1)
当用作 CLI 命令时,我想给最终用户一个关于异常的很好的错误消息,raise
但当它用作导入库时,我想给最终用户一个很好的错误消息。
我entry_points
在我的setup.py
:
entry_points={
'console_scripts': [
'jello=jello.cli:main'
]
}
这很好用,但我无法轻易区分包是在 CLI 上运行还是导入的,因为__name__
总是jello.cli
. 这是因为入口点基本上是照常导入包。
我尝试创建一个__main__.py
文件并将我的入口点指向那里,但这似乎没有什么不同。
我正在考虑检查sys.argv[0]
我的程序名称是否存在,但这似乎是一个脆弱的黑客。(以防用户为命令或其他东西起别名)还有其他想法还是我做错了?现在我一直在as_lib
向我的函数传递一个参数,因此它们的行为会根据它们是作为模块加载还是从 CLI 运行而有所不同,但我想摆脱这种情况。
解决方案
我相信你想要的在 Python 中被称为“主要守卫”。该模块在任何给定时间都知道它的名称。如果模块是从 CLI 执行的,则其名称为__main__
. 因此,您可以做的是将您想要的所有功能放在模块级别的某个函数中,然后您可以在“主要守卫”中以不同于您将其作为库调用的方式调用它。这是“主要后卫”的样子:
def myfunc(thing, stuff):
if not stuff:
raise MyExc
if __name__ == '__main__':
try:
myfunc(x, y)
except MyExc:
sys.exit(1)
在这里,只有在模块作为脚本从命令行执行时,sys.exit 才会在出错时被调用。
推荐阅读
- php - 将产品文件下载链接添加到感谢页面 WooCommerce
- python - 如何找到一行的值连续达到最大值的次数
- grafana - 解释grafana查询
- javascript - 如何在引导程序中添加幻灯片
- azure - 如何为 Azure AppService 配置 access_token 以允许访问通过 Azure Active Directory 保护的两个 FunctionApp?
- batch-file - Scala Huygens Fokker(仅限命令行)v1.88b 不幸地删除了多余的空格
- python - 如何用管道连接子列表的元素?
- javascript - 停止从请求库监听完成事件
- amazon-web-services - 如何设置 VPC 以便所有内部 EC2 使用相同的 EIP 与外部通信?
- c# - 如何使用 C# .NET 3.5 解压缩 7z 存档?