首先找到两个数字的“ 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
答案 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
请注意,在示例中的每一个点,调用函数时,它都使用括号语法。以下是我发布的第一段代码中按顺序进行的所有函数调用:
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)
),恰好是my_function
的值在重新分配之前发生在步骤1 。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)
,lcm
和hcf
行是两个引用同一功能的名称。