python - 如何在不嵌入所有容器内容的情况下转储和保存函数参数?
问题描述
我试图在运行时将所有函数参数保存到容器中。容器对于脚本中运行的所有函数都是通用的。如何确保每次保存函数参数时都不会保存所有容器的内容?
下面的装饰器保存函数参数:
import inspect
from datetime import datetime
import time
def func_logger(method):
def wrapper(*args, **kw):
method_args = inspect.signature(method).bind(*args, **kw).arguments
runtime = str( datetime.now() )
name = method.__name__
module = method.__module__
signature = runtime + ': ' + '.'.join([module, name])
ts = time.time()
result = method(*args, **kw)
te = time.time()
kw['log'][signature] = {}
kw['log'][signature]['time'] = round(te - ts, 2)
kw['log'][signature]['args'] = method_args
return result
return wrapper
还有一个示例函数:
@func_logger
def test(a, b=4, c='blah-blah', *args, **kwargs):
return 4**4**8
当我运行以下代码段时:
log = {}
output = test(1,4,2,4,1,par=1, log=log)
output = test(1,4,2,4,1,par=1, log=log)
log
我收到这个输出:
{'2019-05-17 13:48:25.214094: __main__.test': {'time': 0.0,
'args': OrderedDict([('a', 1),
('b', 4),
('c', 2),
('args', (4, 1)),
('kwargs', {'par': 1, 'log': {...}})])},
'2019-05-17 13:48:25.215092: __main__.test': {'time': 0.0,
'args': OrderedDict([('a', 1),
('b', 4),
('c', 2),
('args', (4, 1)),
('kwargs', {'par': 1, 'log': {...}})])}}
我已经尝试过一种解决方法 - 从字典中删除“日志”条目的功能。但是,此日志中的每个下一项都存储日志的当前内容。所以当我尝试这个时:
list( log.items() )[-1][-1]['args']
输出是这样的:
OrderedDict([('a', 1),
('b', 4),
('c', 2),
('args', (4, 1)),
('kwargs',
{'par': 1,
'log': {'2019-05-17 13:45:45.748722: __main__.test': {'time': 0.0,
'args': OrderedDict([('a', 1),
('b', 4),
('c', 2),
('args', (4, 1)),
('kwargs', {'par': 1, 'log': {...}})])},
'2019-05-17 13:45:45.749221: __main__.test': {'time': 0.0,
'args': OrderedDict([('a', 1),
('b', 4),
('c', 2),
('args', (4, 1)),
('kwargs', {'par': 1, 'log': {...}})])},
'2019-05-17 13:45:45.750218: __main__.test': {'time': 0.0,
'args': OrderedDict(...)}}})])
所以本质上,这样的解决方法是行不通的,因为随着时间的推移,内存会很快被堵塞。
每次我保存函数参数时,装饰器是否有任何方法不会保存日志条目?我宁愿避免每次我想从新函数转储参数时创建一个新的“log = {}”容器。
解决方案
您可以简单地存储 log 参数(如果存在)并将其从以下位置删除**kw
:
def func_logger(method):
def wrapper(*args, **kw):
try:
log = kw['log']
del kw['log']
except KeyError:
log = None
method_args = inspect.signature(method).bind(*args, **kw).arguments
runtime = str( datetime.now() )
name = method.__name__
module = method.__module__
signature = runtime + ': ' + '.'.join([module, name])
ts = time.time()
result = method(*args, **kw)
te = time.time()
if log is not None:
log[signature] = {}
log[signature]['time'] = round(te - ts, 2)
log[signature]['args'] = method_args
return result
return wrapper
推荐阅读
- swift - macOS 上的 SwiftUI - 同时处理单击和双击
- sql - “*”是否确保特定的列排序?
- html - 不需要的中心对齐
- go - 带有授权标头的 307 重定向
- ios - 如何读取 GCDWebServer POST 请求的表单正文
- c# - .net-core Angular:使用 Angular HTTPClient 的 HTTP Post 错误 400
- java - Jackson:如何为包含该子对象作为字段的多个对象包含子对象的不同属性
- python - 未选择任何选项的 Radionbutton 初始化
- excel - 当excel文件中有多个工作表时如何调整此代码
- r - 如何创建一个计算指数总和的循环