[Day1]PythonAdvanced学习笔记-装饰器decorator
[PythonAdvanced] 学习笔记 - Day 1
概览
Date: 2024-11-26 Time Spent: 6 hours
Topics: Decorators Difficulty: ⭐⭐⭐☆☆ (1-5 stars)
学习内容
-
[*args & **kwargs]
-
概念: (使用中
*
是必须的,名称可以根据个人习惯更换)*args is used to send a non-keyworded variable length argument list to the function.
*args
用来传递没有keyword的值。**kwargs allows you to pass keyworded variable length of arguments to a function.
**kwargs
是用来传递有keyword的值。 -
*args Example code
def test_var_args(f_arg, *argv): print("first normal arg:", f_arg) for arg in argv: print("another arg through *argv:", arg) >>> test_var_args('yasoob', 'python', 'eggs', 'test') first normal arg: yasoob another arg through *argv: python another arg through *argv: eggs another arg through *argv: test
-
**kwargs Example code
def greet_me(**kwargs): for key, value in kwargs.items():#遍历字符串 print("{0} = {1}".format(key, value))#以key=value的格式化形式输出 >>> greet_me(name="yasoob") //key=name, value=yasoob name = yasoob
-
-
[Decorators]
-
概念: 不改变原代码的基础上,对函数进行修饰。
-
Example code
def decorator(func): def wrapper(): print("Something is happening before the function is called.") func() print("Something is happening after the function is called.") return wrapper def say_whee(): print("Whee!") say_whee = decorator(say_whee)
-
Example code
def do_twice(func): def wrapper_do_twice(*args, **kwargs): func(*args, **kwargs) func(*args, **kwargs) return wrapper_do_twice @do_twice # greet = do_twice(greet) def greet(name): print(f"Hello {name}") >>> greet(name = "Mia")
-
Example code
def do_twice(func): def wrapper_do_twice(*args, **kwargs): func(*args, **kwargs) func(*args, **kwargs) return func(*args, **kwargs) return wrapper_do_twice @do_twice def return_greeting(name): print("Creating greeting") return f"Hi {name}" >>> return_greeting("Adam") Creating greeting Creating greeting 'Hi Adam'
-
Example code
import functools def do_twice(func): @functools.wraps(func) def wrapper_do_twice(*args, **kwargs): func(*args, **kwargs) return func(*args, **kwargs) return wrapper_do_twice @do_twice def say_whee(): print("Whee!") >>> say_whee <function say_whee at 0x7ff79a60f2f0> >>> say_whee.__name__ 'say_whee' >>> help(say_whee) Help on function say_whee in module whee:
-
Example code
import functools def decorator(func): @functools.wraps(func) def wrapper_decorator(*args, **kwargs): # Do something before value = func(*args, **kwargs) # Do something after return value return wrapper_decorator
-
Timer Example Code
import functools import time def timer(func): """Print the runtime of the decorated function""" @functools.wraps(func) def wrapper_timer(*args, **kwargs): start_time = time.perf_counter() value = func(*args, **kwargs) end_time = time.perf_counter() run_time = end_time - start_time print(f"Finished {func.__name__}() in {run_time:.4f} secs") return value return wrapper_timer @timer def waste_some_time(num_times): for _ in range(num_times): sum([number**2 for number in range(10_000)]) >>> waste_some_time(1) Finished waste_some_time() in 0.0010 secs >>> waste_some_time(999) Finished waste_some_time() in 0.3260 secs
-
练习代码
# *args and **kwargs 传递不定数量的值,如没有规定数量的字符串等
# 当使用 * 解包时,如果传入的是一个字符串,它会将字符串解包为字符序列。
# 当使用 ** 解包时,如果传入的是一个字典,它会将字典解包为关键字参数。
def test_args(value, *args):
print("first:", value)
for arg in args:
print("next:", arg)
# test_args('hello','world','three','four')
def test_kwargs(**kwargs):
for key, value in kwargs.items():
print("{} = {}".format(key, value))
# test_kwargs(name='GPT',age='0.5 year',sex='none')
def test_args_and_kwargs(name, age, sex):
print("name:", name)
print("age:", age)
print("sex:", sex)
args = ("GPT", "0.5 year", 'none')
# test_args_and_kwargs(*args)
kwargs = {"name": 'GPT', "sex": 'none', "age": '0.5 year'}
# test_args_and_kwargs(**kwargs) #使用**输出时需要注意列表里的key要与函数里的key对应
def decorator(func):
def wrapper(): # 包装内容
print("before the function")
func()
print("after the function")
return wrapper
def say_hello():
print("hello!")
# say_hello() #装饰前
say_hello = decorator(say_hello) # 装饰后的
# say_hello()
@decorator # 文法糖的装饰功能与say_hello = decorator(say_hello)功能一致
def say_hi():
print("hi")
# say_hi()
import functools
def do_twice(func):
@functools.wraps(func) # 使用 @ functools.wraps裝飾器,它將保留有關原始函數的資訊
def wrapper(*args, **kwargs): # 接受任意數量的參數並將它們傳遞給它修飾的函數
func(*args, **kwargs)
func(*args, **kwargs)
return func(*args, **kwargs) # 保证如果与需求,可以回传函数值
return wrapper
@do_twice
def say_hello(name):
print("hello!", name)
# say_hello('Arden')
info = "Arden"
# say_hello(*info) #无法实现,*会将“Arden”解包为字符序列,因此有五个参数,与函数不符。
# say_hello(info)
info_me = {"name": "Arden"}
# say_hello(**info_me)
import functools # 装饰器模板
import time
def timer(func):
# 用来统计函数运行时间
@functools.wraps(func)
def wrapper_decorator(*args, **kwargs):
start_time = time.time() # 统计开始时时间
value = func(*args, **kwargs)
end_time = time.time() # 记结束时间
time_taken = end_time - start_time #时间差值
print("It takes", time_taken, "seconds")
return value
return wrapper_decorator
@timer
def waste(num):
for i in range(num):
sum([i**2 for i in range(10000)]) #计算(1+...+2i)的和(i<=10000)
#waste(1)
#waste(999)
遇见的挑战难及解决方法和笔记点见注释。
学习资源
- [Python Tips]: A book of many contents like generators, decorators, mutation and so on.
- [Real Python]: Primer on Python Decorators.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南