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

时间:2018-10-06 10:59:22

标签: python python-3.x python-decorators

首先找到两个数字的“ lcm”,我做了一个函数lcm(a, b)。然后我想到也要找到“ hcf”,所以我做了一个装饰器decor并在其中定义了一个函数hcf(a, b)。然后,我只输入了函数的名称就返回了该函数,但没有在括号中加上它,但仍可以使用。即使我没有使用方括号,我也无法理解此功能为何起作用。

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)

输出:

hcf is 2
lcm is 4

2 个答案:

答案 0 :(得分:6)

我认为您不懂装饰。让我们做一个最小的例子。

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,它返回两个参数的和,还有一个装饰器,该装饰器将打印出它装饰的任何函数的结果。

请注意

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

等同于

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

my_function = my_decorator(my_function)

由于my_decorator接受一个函数作为参数(此处我们赋予它my_function)并返回一个新函数 new_function(无需调用!) ,我们有效地覆盖了my_function,因为我们将名称重新分配给了my_decorator返回的任何内容。

实际情况:

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

请注意,在示例中的每一个点,调用函数时,它都使用括号语法。以下是我发布的第一段代码中按顺序进行的所有函数调用:

  1. my_decorator(my_function)被调用,并且返回值被重新分配为名称my_function。这可以通过@语法实现,也可以在等效的代码片段中更明确地实现。
  2. my_function(1, 2)被调用。此时,my_function是装饰者返回的new_function。将其解析为new_function(1, 2)
  3. new_function的正文中,我们提供给my_decorator的参数称为(result = some_function(*args, **kwargs)),恰好是my_function的值在重新分配之前发生在步骤1
  4. print被呼叫。

如果您想了解尽管new_function已经从调用中返回,some_function仍然保持my_decorator的情况,建议您查看主题免费变量封包

答案 1 :(得分:1)

如您所见,

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

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

等同于

def lcm(a, b):
    // ...

lcm = decor(lcm)

执行此操作后,lcm引用函数hcf。因此,现在调用lcm(2, 4)将执行hcf中的代码。我认为这里的关键是要了解在lcm(2, 4)lcmhcf行是两个引用同一功能的名称。