如下是使用 Python 中函数特性的例子:
# 1. Assigning Functions to Variablessay_hello = greetprint(say_hello("Alice")) # Output: Hello, Alice!# 2. Pass function as an argumentdef apply_function(func, value): return func(value)def uppercase(text): return text.upper()result = apply_function(uppercase, "hello")print(result) # Output: HELLO# 3. Return function from another function (Nested Function)def make_multiplier(n): def multiplier(x): return x * n return multiplierdouble = make_multiplier(2)print(double(5)) # Output: 10
结合以上特性,可以实现一个简单的装饰器,实现计时功能
Tips: 建议使用 functools.wraps
保留原函数的元信息,如__name__、__doc__
等
from functools import wrapsfrom time import timedef simple_decorator(func): @wraps(func) # 此注解用于保留func的元信息 def wrapper(*args, **kwargs): print(f"function <{func.__name__}> is called") start_time = time() result = func(*args, **kwargs) print(f"Function execution time: {time() - start_time}") return result return wrapper@simple_decoratordef calculate(): sum = 0 for i in range(1000000): sum += i print(sum)# 上述代码等价于# @simple_decorator syntax 等价于 calculate = simple_decorator(calculate)calculate()[OUTPUT]function <calculate> is called499999500000Function execution time: 0.16027212142944336
Python 允许使用多个装饰器,可以通过 @decorator1
@decorator2
… @decoratorN
的方式来实现
from functools import wrapsdef star(func): @wraps(func) def wrapper(*args, **kwargs): print("*" * 30) func(*args, **kwargs) print("*" * 30) return wrapperdef hyphen(func): @wraps(func) def wrapper(*args, **kwargs): print("-" * 30) func(*args, **kwargs) print("-" * 30) return wrapper@star@hyphendef greet(name): print(f"Hello, {name}!")greet("Python")[OUTPUT]******************************------------------------------Hello, Python!------------------------------******************************
from functools import lru_cache@lru_cache(maxsize=128)def fibonacci(n): if n < 2: return n else: return fibonacci(n-1) + fibonacci(n-2)
class Person: def __init__(self, name, age): self._name = name self._age = age @property def name(self): return self._name @name.setter def name(self, value): self._name = value @property def age(self): return self._age @age.setter def age(self, value): self._age = valueperson = Person("Alice", 25)print(person.name) # Output: Aliceperson.name = "Bob"print(person.name) # Output: Bob
What are “first-class” objects? —— StackOverFlow
Decorators Pattern in Python