簡體   English   中英

如何用錯誤處理程序裝飾可迭代對象?

[英]How to decorate iterables with an error handler?

假設我們有兩種方法:一種返回列表,另一種返回迭代器。 因此,在兩個返回值都是可迭代的意義上,它們非常具有可比性。

我想編寫一個裝飾器來捕獲迭代中的錯誤。 問題是迭代器在沒有迭代的情況下返回,因此不會捕獲任何錯誤。

在下面的代碼中, wrapped_properly裝飾器通過提供兩個單獨的包裝器來解決這個問題,一個是默認的包裝器 ( wrapper ),另一個是專門用於生成器函數的 ( generatorfunctionwrapper )。 該方法感覺非常復雜和冗長。

from inspect import isgeneratorfunction
from functools import wraps

def failing_generator():
    for i in range(1, 5):
        if i % 2 == 0:
            print('I dont like even numbers.')
            raise ValueError(i)
        yield i

def wrapped_badly(fn):
    @wraps(fn)
    def wrapper(*args, **kwargs):
        try:
            return fn(*args, **kwargs)
        except ValueError as err:
            print('Not to worry.')
    return wrapper

def wrapped_properly(fn):
    @wraps(fn)
    def wrapper(*args, **kwargs):
        try:
            return fn(*args, **kwargs)
        except ValueError as err:
            print('Not to worry.')
    
    @wraps(fn)
    def generatorfunctionwrapper(*args, **kwargs):
        try:
            yield from fn(*args, **kwargs)
        except ValueError as err:
            print('Not to worry.')

    if isgeneratorfunction(fn):
        return generatorfunctionwrapper
    else:
        return wrapper

for x in wrapped_properly(failing_generator)():
    print(x)
# Prints:
# 1
# I dont like even numbers.
# Not to worry.

for x in wrapped_badly(failing_generator)():
    print(x)
# Prints:
# 1
# I dont like even numbers.
# Traceback (most recent call last):
# ...
# ValueError: 2

有沒有更好/更pythonic的方法來做到這一點?

我建議無論原始 function 返回什么可迭代對象,都返回一個迭代器。

def wrapped(fn):
    def wrapper(*args, **kwargs):
        try:
            yield from iter(fn(*args, **kwargs))
        except ValueError as err:
            print('Not to worry')

    return wrapper

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM