在Python中包装单个函数调用

在Python中包装单个函数调用,python,imaplib,Python,Imaplib,我正在编写一个脚本,使用imaplib库从IMAP服务器请求一些数据。启动连接(c)后,我进行以下调用: rv, data = c.login(EMAIL_ACCOUNT, EMAIL_PASS) if rv != 'OK': print('login error') else: print(rv, data) rv, mailboxes = c.list() if rv != 'OK': print('mailbox error') else: print(r

我正在编写一个脚本,使用
imaplib
库从IMAP服务器请求一些数据。启动连接(
c
)后,我进行以下调用:

rv, data = c.login(EMAIL_ACCOUNT, EMAIL_PASS)
if rv != 'OK':
    print('login error')
else:
    print(rv, data)

rv, mailboxes = c.list()
if rv != 'OK':
    print('mailbox error')
else:
    print(rv, data)

rv, data = c.select(EMAIL_FOLDER)
if rv != 'OK':
    print('folder error')
else:
    print(rv, data)

我如何重写它以使用某种包装函数来重用检查错误代码和打印数据的逻辑?我假设该函数将错误消息作为参数,并执行命令(
select
login
,等等)。如何通过在参数中传递选择连接函数的名称来调用该函数?

要重复使用任何代码,请查看保持不变的内容(例如,
rv
data
按该顺序从
imaplib
调用中出来,并且
rv='OK'
表示一切正常)写一次涉及他们的逻辑。然后查看更改的内容(例如,需要打印的确切错误消息)。参数化更改的内容,如本例中的
description
参数更改错误消息:

def check(description, rvdata):
    rv, data = rvdata
    if rv == 'OK':
        print(data)
        return data
    else:
        print(description + ' error')
        return None

data = check('login', c.login(EMAIL_ACCOUNT, EMAIL_PASS))
mailboxes = check('mailbox', c.list())
selection = check('folder', c.select(EMAIL_FOLDER))

据我所知,您希望检查装饰师以完成任务

class Wrapper:
    def __init__(self, error_message):
        self.error_message = error_message

    def __call__(self, wrapped):
        def func(*args, **kwargs):
            rv, data = wrapped(*args, **kwargs)
            if rv=="OK":
                return(rv, data)
            else:
                print(self.error_message)
                return(rv, data)
        return func

@Wrapper("Folder Error")
def select(email_folder):
    return "OK", "OLOLO"

@Wrapper("Folder Error")
def select_err(email_folder):
    return "FAIL", "OLOLO"

print select("")
print select_err("")
屈服

('OK', 'OLOLO')
Folder Error
('FAIL', 'OLOLO')
您可以检查Wrapper的
\uuuuu call\uuuu
函数中的reply,并以您想要的方式处理它。例如,如果
rv
不等于“OK”,则可以返回“False”或引发错误


但对你的案子来说可能太复杂了

不清楚你在问什么。是的,您可以编写一个包装函数(
rv,data=handle\u error(c.login(…)
)和/或将方法的名称传递给另一个函数。您尝试了什么,有什么问题吗?
def check(rv,data,msg):…
并用作
check(rv,data,'folder error')
?@jornsharpe基本上,我想将其简化为一个函数,将操作(select,list,login)作为参数,同时显示一条错误消息。我可以将函数调用(例如
c.list()
)作为参数传递给“handle”函数吗?可以,只要传递方法本身(
c.list
,注意缺少括号);它们是Python的第一流。但是你需要正确地处理参数。你可能需要研究python装饰器。是的,有点太复杂了。不过,还是要感谢您选择了另一种方法!我以前从未想过使用对象实例作为装饰器。这是一个很酷的把戏。@jez,一开始我很难理解装饰师,直到最近才意识到如何使用它。我在某处查到了这个把戏。)