Python类方法,什么时候返回self?

2023-12-06

我很困惑何时在类中返回 self 以及何时返回一个可能或不可能用于检查方法是否正确运行的值。

def api_request(self, data):
    #api web request code
    return response.text
def connect(self):
    #login to api, set some vars defined in __init__
    return self
def send_message(self, message):
    #send msg code
    return self

上面有一些例子。 api_request 我知道必须有文本响应。但是对于 send_message 我应该返回什么?

然后将其转换为字典以检查键是否存在,否则引发错误)。

它应该返回 True、response->dict 还是 self?

提前致谢


由于错误往往作为异常传递,因此成功/失败返回值很少有用,因此许多对象修饰符函数最终根本没有返回值,或者更准确地说,返回None,因为你不能什么都不返回。 (考虑一些 Python 的内置对象,例如list, where append and extend return None, and dict, where dict.update回报None.)

还是归来self对于链接方法调用来说很方便,即使有些 Python 爱好者不喜欢它。请参阅 kindall 的回答内部类方法应该返回值还是只修改Python中的实例变量?例如。


编辑以根据评论添加一些示例:

您“应该”返回什么(或引发异常,在这种情况下,“什么异常”)取决于问题。你想要send_message()等待响应、验证该响应并验证其是否良好?如果是这样,您是否希望它在没有响应、验证失败或响应有效但显示“消息被拒绝”时引发错误?如果是这样,你想要吗不同的每次失败的错误等?一种合理的(对于某些合理的值)方法是捕获具有“基本”异常的所有故障,并使每种“类型”的故障都是其派生:

class ZorgError(Exception):      # catch-all "can't talk via the Zorg-brand XML API"
    pass

class ZorgRemoteDown(ZorgError): # connect or send failed, or no response/timeout
    pass

class ZorgNuts(ZorgError):       # remote response incomprehensible
    pass

class ZorgDenied(ZorgError):     # remote says "permission denied"
    pass

# add more if needed

现在你的一些函数可能看起来像这样(注意,这些都没有经过测试):

def connect(self):
    """connect to server, log in"""
    ... # do some prep work
    addr = self._addr
    try:
        self._sock.connect(addr)
    except socket.error as err:
        if err.errno == errno.ECONNREFUSED: # server is down
            raise ZorgRemoteDown(addr)      # translate that to our Zorg error
        # add more special translation here if needed
        raise                               # some other problem, propagate it
    ... # do other stuff now that we're connected, including trying to log in
    response = self._get_response()
    if response == 'login denied'   # or whatever that looks like
        raise ZorgDenied()          # maybe say what exactly was denied, maybe not
    # all went well, return None by not returning anything

def send_message(self, msg):
    """encode the message in the way the remote likes, send it, and wait for
    a response from the remote."""
    response = self._send_and_wait(self._encode(msg))
    if response == 'ok':
        return
    if response == 'permission denied':
        raise ZorgDenied()
    # don't understand what we got back, so say the remote is crazy
    raise ZorgNuts(response)

然后你需要一些“内部”函数,如下所示:

def _send_and_wait(self, raw_xml):
    """send raw XML to server"""
    try:
        self._sock.sendall(raw_xml)
    except socket.error as err:
        if err.errno in (errno.EHOSTDOWN, errno.ENETDOWN) # add more if needed
            raise ZorgRemoteDown(self._addr)
        raise
    return self._get_response()

def _get_response(self):
    """wait for a response, which is supposedly XML-encoded"""
    ... some code here ...
    if we_got_a_timeout_while_waiting:
       raise ZorgRemoteDown(self._addr)
    try:
        return some_xml_decoding_stuff(raw_xml)
    except SomeXMLDecodeError:
        raise ZorgNuts(raw_xml) # or something else suitable for debug

您可以选择不翻译socket.error根本没有,并且没有所有错误都是你自己的;也许你可以把你的错误压缩成ValueError and KeyError等等。

这些选择就是编程的全部内容!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python类方法,什么时候返回self? 的相关文章

随机推荐