python - 用于包装尝试的通用装饰器除了在 python 中?

标签 python try-catch wrapper decorator

我会与很多我没有编写的深度嵌套的 json 进行交互,并且想让我的 python 脚本对无效输入更加“宽容”。我发现自己在编写涉及 try-except block ,而宁愿将可疑的函数包装起来。

我知道吞下异常是一个糟糕的策略,但我宁愿稍后打印和分析它们,而不是实际停止执行。在我的用例中,继续循环执行比获取所有键更有值(value)。

这是我现在正在做的事情:

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):

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) 包装在某个函数中,该函数将执行停止异常转换为空字段,并打印到标准输出。前者将是一种逐项跳过 - 在该键不可用的情况下,它记录为空白并继续前进 - 后者是行跳过,如果任何字段不起作用,则整个记录是跳过。

我的理解是某种包装器应该能够解决这个问题。这是我尝试过的,带有一个包装器:

def f(func):
   def silenceit():
      try:
         func(*args,**kwargs)
      except:
         print('Error')
      return(silenceit)

这就是它不起作用的原因。调用一个不存在的函数,它不会 try catch 它:

>>> f(meow())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'meow' is not defined

在我什至添加一个空白返回值之前,我想让它正确地 try catch 。如果该功能有效,这将打印“错误”,对吗?

包装函数是正确的方法吗?

更新

我在下面得到了很多非常有用、有用的答案,并感谢他们——但我已经编辑了上面使用的示例来说明我试图捕获的不仅仅是嵌套的键错误,我正在寻找一个专门为...包装 try-catch 的函数。

  1. 当方法不存在时。
  2. 当一个对象不存在,并且正在获取一个调用它的方法时。
  3. 当一个不存在的对象作为函数的参数被调用时。
  4. 这些东西的任意组合。
  5. 奖励,当函数不存在时。

最佳答案

这里有很多很好的答案,但我没有看到任何可以解决您是否可以通过装饰器完成此任务的问题。

简短的回答是“不”,至少在不对代码进行结构更改的情况下不会。装饰器在功能级别上运行,而不是在单个语句上运行。因此,为了使用装饰器,您需要将要装饰的每个语句移动到自己的函数中。

但请注意,您不能只将赋值本身放在修饰函数中。您需要从修饰函数中返回 rhs 表达式(要赋值的值),然后在外面进行赋值。

根据您的示例代码,可以使用以下模式编写代码:

@return_on_failure('')
def computeA():
    item['a'] = myobject.get('key').METHOD_THAT_DOESNT_EXIST()

item["a"] = computeA()

return_on_failure 可能类似于:

def return_on_failure(value):
  def decorate(f):
    def applicator(*args, **kwargs):
      try:
         return f(*args,**kwargs)
      except:
         print('Error')
         return value

    return applicator

  return decorate

关于python - 用于包装尝试的通用装饰器除了在 python 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15572288/

相关文章:

python - 如何访问 pywinauto 中的控件标识符

python - 在 python 中可视化推文长度

html - #CSS Wrapper 无法识别内容

r - 如何在R中的for循环中捕获错误?

c++ - 如何为允许表达语法的 cout 编写函数包装器?

c - 将 C dll 方法导出到 c# P/Invoke

python - oct2py 没有看到 OCTAVE_EXECUTABLE 环境变量 (Windows)

python - 按最低值对元组列表进行排序

powershell - 尝试仅在终止异常时起作用吗?

java - 如何在 Java 中使用自定义异常?我已按照步骤操作,但我的 catch 条款无法正常工作