如何通过键入函数名称而不是使用括号来调用python中的函数

how a function in python is getting called by just typing the name of function and not using brackets

首先,为了找到两个数的"lcm",我做了一个函数lcm(a, b)。然后我也想到找到"hcf",于是我做了一个装饰器decor,并在其中定义了一个函数hcf(a, b)。然后我只输入了函数的名称就返回了这个函数,虽然没有用括号括起来,但它仍然有效。我不明白为什么这个函数可以工作,即使我没有使用括号。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def decor(lcm_arg):        # just to practice decorators
    def hcf(a, b):
        if a > b:
            a, b = b, a
        while True:
            if b % a == 0:
                print("hcf is", a)
                break
            else:
                a, b = b % a, a
        return lcm_arg(a, b)
    return hcf              # how hcf function is working without using brackets

@decor
def lcm(a, b):
    if a > b:
        a, b = b, a
    for x in range(b, a*b+1, b):
        if x % a == 0:
            print("lcm is", x)
            break


lcm(2, 4)

输出:

1
2
hcf is 2
lcm is 4


我觉得你不懂装饰。让我们做一个最小的例子。

1
2
3
4
5
6
7
8
9
10
11
12
def my_decorator(some_function):        
    def new_function(*args, **kwargs):
        'announces the result of some_function, returns None'
        result = some_function(*args, **kwargs)
        print('{} produced {}'.format(some_function.__name__, result))
    return new_function # NO FUNCTION CALL HERE!

@my_decorator
def my_function(a, b):
    return a + b

my_function(1, 2) # will print"my_function produced 3"

我们有一个简单的函数my_function,它返回两个参数的和,还有一个decorator,它将打印出它所修饰的任何函数的结果。

注意

1
2
3
@my_decorator
def my_function(a, b):
    return a + b

等于

1
2
3
4
def my_function(a, b):
    return a + b

my_function = my_decorator(my_function)

因为my_decorator接受一个函数作为参数(这里我们给它my_function并返回一个新函数new_function(不调用它!)我们有效地覆盖my_function,因为我们将名称重新分配给my_decorator返回的任何内容。

行动中:

1
2
>>> my_function(1, 2)
my_function produced 3

注意,在示例中的每一点上,当调用函数时,都会出现括号语法。以下是我发布的第一个代码块中发生的所有函数调用,顺序如下:

  • 调用my_decorator(my_function)并将返回值重新分配给名称my_function。这要么通过@语法发生,要么在等效代码片段中更明确地发生。
  • my_function(1, 2)。此时,my_function是装饰师返回的new_function。大脑将其解析为new_function(1, 2)
  • new_function的主体内,我们给my_decorator的论点称为(result = some_function(*args, **kwargs),它恰好是步骤1中发生的重新分配之前my_function的值。
  • print
  • 如果您想了解new_function是如何持有some_function,尽管my_decorator已经从其调用中返回,我建议您研究主题自由变量和闭包。


    正如您注意到的,return hcf不调用函数,因为没有括号。decor函数用作修饰符,它重新分配名称lcm以引用返回的函数。我的意思是

    1
    2
    3
    @decor
    def lcm(a, b):
        // ...

    等于

    1
    2
    3
    4
    def lcm(a, b):
        // ...

    lcm = decor(lcm)

    执行后,lcm指函数hcf。所以调用lcm(2, 4)现在执行hcf中的代码。我认为这里的关键是要理解,在lcm(2, 4)行,lcmhcf是指同一函数的两个名称。