首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python类方法,什么时候返回self?

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

Stack Overflow用户
提问于 2013-07-04 07:58:53
回答 2查看 7.1K关注 0票数 2

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

代码语言:javascript
运行
复制
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,我应该返回什么呢?

然后将其转换为dict以检查密钥是否存在,否则引发错误)。

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

提前感谢

EN

回答 2

Stack Overflow用户

发布于 2013-07-04 08:10:13

由于错误倾向于作为异常传递,因此成功/失败返回值很少有用,因此许多对象修饰符函数最终根本没有返回值-或者更准确地说,返回None,因为您根本不能返回任何东西。(考虑一些Python的内置对象,比如list,其中appendextend返回None,以及dict,其中dict.update返回None。)

不过,返回self对于链接方法调用还是很方便的,即使有些Pythonistas不喜欢这样做。例如,请参阅Should internal class methods returnvalues or just modify instance variables in python?中的金德尔答案。

编辑以添加一些基于注释的示例:

你“应该”返回什么-或者引发一个异常,在这种情况下,“什么异常”在问题上-depends。是否希望send_message()等待响应、验证该响应并验证其是否正常?如果是这样,您是否希望在没有响应、验证失败或响应有效但显示"message rejected“的情况下引发错误?如果是这样,您是否希望每个失败都有不同的错误,等等?一种合理的(对于某些合理的值)方法是用“基本”异常捕获所有故障,并使每种“类型”的故障都是该异常的派生:

代码语言:javascript
运行
复制
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

现在,您的一些函数可能如下所示(请注意,这些函数都没有经过测试):

代码语言:javascript
运行
复制
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)

然后你需要一些像这样的“内部”函数:

代码语言:javascript
运行
复制
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,也不会有自己的所有错误;例如,您可以将错误压缩到ValueErrorKeyError中,依此类推。

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

票数 3
EN

Stack Overflow用户

发布于 2013-07-04 08:02:05

通常,python中的对象是可变的。因此,您不会返回self,因为您在方法中所做的修改会反映在对象本身中。

使用您的示例:

代码语言:javascript
运行
复制
api = API() # initialise the API
if api.connect(): # perhaps return a bool, indicating that the connection succeeded
    api.send_message() # you now know that this API instance is connected, and can send messages
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17459970

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档