最近在看effective python原版第2版,看到元类最后一个关于引入类装饰器的例子,代码如下:
我原本一直以为自己了解*args, **kwargs是怎么解析的,但看到这个运行结果后就迷惑了……
比如这句:trace_dict = TraceDict([('hi', 1)])
应该是触发初始化__init__,kwargs为空字典,但args最后打印出来怎么变成这个元组了:({'hi': 1}, [('hi', 1)]),我理解的应该只包含[('hi', 1)],前面那个元素{'hi': 1}估计是从super().__init__中解析出来的,直观上应该是dict类输入一个[(key1,value1),(key2,value2),...]这样的列表,然后dict类整合成一个字典数据结构,可我不明白args怎么变了……
from functools import wraps
def trace_func(func):
if hasattr(func, 'tracing'):
return func
@wraps(func)
def wrapper(*args, **kwargs):
result = None
try:
result = func(*args, **kwargs)
return result
except Exception as e:
result = e
raise
finally:
print(f'{func.__name__}({args!r}, {kwargs!r}) -> {result!r}')
wrapper.tracing = True
return wrapper
class TraceDict(dict):
@trace_func
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@trace_func
def __setitem__(self, *args, **kwargs):
return super().__setitem__(*args, **kwargs)
@trace_func
def __getitem__(self, *args, **kwargs):
return super().__getitem__(*args, **kwargs)
trace_dict = TraceDict([('hi', 1)])
trace_dict['there'] = 2
trace_dict['hi']
try:
trace_dict['does not exist']
except KeyError:
pass
else:
assert False
--
FROM 113.247.67.*