我了解将函数作为参数传递给其他函数的过程,但是,由于C#背景的原因,我不了解该函数的必要性。
有人可以让我知道某些首选的方案吗?
将函数传递给函数允许参数化行为。这与将值传递到允许参数化数据的函数相同。
def is_greater(what: int, base: int):
if what > base: # fixed behaviour, parameterised data
print(f'{what} is greater')
def is_valid(what: int, condition: 'Callable'):
if condition(what): # parameterised behaviour
print(f'{what} is valid')
一些常见的用例包括:
map
,filter
以及将某些行为应用于可迭代对象的其他对象。这些函数本身仅实现“应用于每个元素”部分,但是可以将其换出:
>>> print(*map(float, ['1', '2', '3.0'])
1.0 2.0 3.0
在这种情况下,通常使用alambda
来定义动态行为。
>>> print(sorted(
... ['Bobby Tables', 'Brian Wayne', 'Charles Chapeau'],
... key=lambda name: name.split()[1]), # sort by last name
... )
['Charles Chapeau', 'Bobby Tables', 'Brian Wayne']
函数装饰器,用于包装具有其他行为的函数。
def print_call(func):
"""Decorator that prints the arguments its target is called with"""
def wrapped_func(*args, **kwargs):
print(f'call {func} with {args} and {kwargs}')
return func(*args, **kwargs)
return wrapped_func
@print_call
def rolling_sum(*numbers, initial=0):
totals = [initial]
for number in numbers:
totals.append(totals[-1] + number)
return totals
rolling_sum(1, 10, 27, 42, 5, initial=100)
# call <function rolling_sum at 0x10ed6fd08> with ([1, 10, 27, 42, 5],) and {'initial': 100}
每次您看到应用了一个装饰器的@
函数都是一个高阶函数。
在其他时间,上下文,条件,线程甚至进程执行的回调和有效负载。
def call_after(delay: float, func: 'Callable', *args, **kwargs):
"""Call ``func(*args, **kwargs)`` after ``delay`` seconds"""
time.sleep(delay)
func(*args, **kwargs)
thread = threading.Thread(
target=call_after, # payload for the thread is a function
args=(1, print, 'Hello World'))
thread.start()
print("Let's see what happens...")
# Let's see what happens...
#
# Hello World
传递函数而不是值可以模拟惰性计算。
def as_needed(expensive_computation, default):
if random_condition():
return expensive_computation()
return default
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句