#!/usr/bin/env python3
import click

@click.command()
@click.option('--desiredrange', '-r', default=1)

def main(desiredrange):
    print(desiredrange)
    print('Abu can cn')

main()
print('!')

运行上面的代码会在终端中显示以下内容:

1

Abu can cn

但我不明白

This scenario is true for other variations of code that include ANYTHING after the main() function. The script exits after executing this function. This is also true for any function i.e. if I placed the print('!') inside another function, then called that function after main(), the script exits after main(), ignoring the second function.

如果我删除了‘Click’,则代码如下所示:

#!/usr/bin/env python3

def main():
    print(1)
    print('Abu can cn')

main()
print('!')

我将把以下内容打印到航站楼:

1

Abu can cn

我可以在main()之后执行其他函数,以及其他命令.我使用./script.py(应用的chmod+x script.py)从终端运行该脚本.我也没有从这两个场景中得到任何错误.

这是为什么?

推荐答案

您定义的名为main的函数实际上不是第main()行直接调用的函数.取而代之的是,这两个decorator 正在创建一个新值,该值使函数wraps.这个Callable(我不认为它一定是一个函数,而是click.core.Command的一个可调用实例;我没有深入研究代码以了解到底发生了什么.)调用以某种方式引发SystemExit,因此您的脚本在"new"main实际返回之前就退出了.

您可以通过显式捕获main引发的SystemExit并忽略它来确认这一点.这允许执行脚本的其余部分.

try:
    main()
except SystemExit:
    pass
print('!!!!')

请记住,修饰符语法只是函数应用程序的快捷方式.使用该语法,您可以将代码重写为

import click

def main(desiredrange):
    print(desiredrange)
    print('abcd')

x = main

main = click.command(click.option('--desiredrange', '-r', default=1)(main))

y = main
assert x is not y

main()
print('!!!!')

由于断言通过了,这确认绑定到main的值不是原始函数,而是其他函数.

Python相关问答推荐

在上下文管理器中更改异常类型

点到面的Y距离

未删除映射表的行

如何使用html从excel中提取条件格式规则列表?

在Polars(Python库)中将二进制转换为具有非UTF-8字符的字符串变量

Mistral模型为不同的输入文本生成相同的嵌入

基于字符串匹配条件合并两个帧

如何在Python数据框架中加速序列的符号化

Godot:需要碰撞的对象的AdditionerBody2D或Area2D以及queue_free?

Scrapy和Great Expectations(great_expectations)—不合作

字符串合并语法在哪里记录

不能使用Gekko方程'

如何从列表框中 Select 而不出错?

使用Python查找、替换和调整PDF中的图像'

幂集,其中每个元素可以是正或负""""

为什么t sns.barplot图例不显示所有值?'

如何将泛型类类型与函数返回类型结合使用?

Autocad使用pyautocad/comtypes将对象从一个图形复制到另一个图形

比较两个有条件的数据帧并删除所有不合格的数据帧

pytest、xdist和共享生成的文件依赖项