一般装饰器包装尝试除python中? [英] General decorator to wrap try except in python?
问题描述
我将与许多我未编写的深层嵌套json进行交互,并希望使我的python脚本更原谅无效的输入。我发现自己写的是try-except块,宁愿只包装可疑函数。
I'd interacting with a lot of deeply nested json I didn't write, and would like to make my python script more 'forgiving' to invalid input. I find myself writing involved try-except blocks, and would rather just wrap the dubious function up.
我知道吞噬异常是一个不好的政策,但我宁愿宁愿它们在以后打印和分析,而不是实际停止执行。在我的用例中,继续获取循环比获取所有键更有价值。
I understand it's a bad policy to swallow exceptions, but I'd rather prefer they to be printed and analysed later, than to actually stop execution. It's more valuable, in my use-case to continue executing over the loop than to get all keys.
这是我现在正在做的事情:
Here's what I'm doing now:
try:
item['a'] = myobject.get('key').METHOD_THAT_DOESNT_EXIST()
except:
item['a'] = ''
try:
item['b'] = OBJECT_THAT_DOESNT_EXIST.get('key2')
except:
item['b'] = ''
try:
item['c'] = func1(ARGUMENT_THAT_DOESNT_EXIST)
except:
item['c'] = ''
...
try:
item['z'] = FUNCTION_THAT_DOESNT_EXIST(myobject.method())
except:
item['z'] = ''
这就是我想要的(1):
Here's what I'd like, (1):
item['a'] = f(myobject.get('key').get('subkey'))
item['b'] = f(myobject.get('key2'))
item['c'] = f(func1(myobject)
...
或(2):
@f
def get_stuff():
item={}
item['a'] = myobject.get('key').get('subkey')
item['b'] = myobject.get('key2')
item['c'] = func1(myobject)
...
return(item)
...在某些情况下,我可以包装单个数据项(1)或主函数(2)该函数将暂停执行的异常转换为空字段,并打印到stdout中。前者将是逐项跳过的操作-在该键不可用的情况下,它将记录为空白然后继续操作-后者是行跳过,如果任何字段都不起作用,则整个记录为
...where I can wrap either the single data item (1), or a master function (2), in some function that turns execution-halting exceptions into empty fields, printed to stdout. The former would be sort of an item-wise skip - where that key isn't available, it logs blank and moves on - the latter is a row-skip, where if any of the fields don't work, the entire record is skipped.
我的理解是某种包装器应该能够解决此问题。这是我用包装纸尝试过的方法:
My understanding is that some kind of wrapper should be able to fix this. Here's what I tried, with a wrapper:
def f(func):
def silenceit():
try:
func(*args,**kwargs)
except:
print('Error')
return(silenceit)
这就是为什么它不起作用的原因。调用一个不存在的函数,它不会尝试将其删除:
Here's why it doesn't work. Call a function that doesn't exist, it doesn't try-catch it away:
>>> f(meow())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'meow' is not defined
在添加空白返回值之前,我希望它能正确尝试捕获。如果该功能有效,则将显示错误,对吗?
Before I even add a blank return value, I'd like to get it to try-catch correctly. If the function had worked, this would have printed "Error", right?
包装函数是否是此处的正确方法?
Is a wrapper function the correct approach here?
UPDATE
我在下面有很多非常有用的有用的答案,谢谢你的支持-但是我已经编辑了上面的示例,以说明我除了捕获嵌套的键错误以外,我正在寻找一种专门为try-catch封装的函数...
I've had a lot of really useful, helpful answers below, and thank you for them---but I've edited the examples I used above to illustrate that I'm trying to catch more than nested key errors, that I'm looking specifically for a function that wraps a try-catch for...
- 当方法不存在时。
- 当对象不存在并正在调用一个方法时。
- 将不存在的对象作为函数的参数调用时。
- 这些东西的任何组合。
- 奖金,当函数不存在时。
- When a method doesn't exist.
- When an object doesn't exist, and is getting a method called on it.
- When an object that does not exist is being called as an argument to a function.
- Any combination of any of these things.
- Bonus, when a function doesn't exist.
推荐答案
您可以使用defaultdict和上下文管理器方法如Raymond Hettinger在PyCon 2013演示文稿中概述的那样
You could use a defaultdict and the context manager approach as outlined in Raymond Hettinger's PyCon 2013 presentation
from collections import defaultdict
from contextlib import contextmanager
@contextmanager
def ignored(*exceptions):
try:
yield
except exceptions:
pass
item = defaultdict(str)
obj = dict()
with ignored(Exception):
item['a'] = obj.get(2).get(3)
print item['a']
obj[2] = dict()
obj[2][3] = 4
with ignored(Exception):
item['a'] = obj.get(2).get(3)
print item['a']
这篇关于一般装饰器包装尝试除python中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!