一般装饰器包装尝试除python中? [英] General decorator to wrap try except in python?

查看:81
本文介绍了一般装饰器包装尝试除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...


  1. 当方法不存在时。

  2. 当对象不存在并正在调用一个方法时。

  3. 将不存在的对象作为函数的参数调用时。

  4. 这些东西的任何组合。

  5. 奖金,当函数不存在时。

  1. When a method doesn't exist.
  2. When an object doesn't exist, and is getting a method called on it.
  3. When an object that does not exist is being called as an argument to a function.
  4. Any combination of any of these things.
  5. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆