python类什么时候加self_Python类方法,何时返回self?

I'm confused as to when to return self inside a class and when to return a value which may or may not possibly be used to check the method ran correctly.

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

So above theres a few examples. api_request I know having the text response is a must. But with send_message what should I return?

which is then converted to a dict to check a key exists, else raise error).

Should it return True, the response->dict, or self?

Thanks in advance

解决方案

Since errors tend to be delivered as exceptions and hence success/fail return values are rarely useful, a lot of object-modifier functions wind up with no return value at all—or more precisely, return None, since you can't return nothing-at-all. (Consider some of Python's built-in objects, like list, where append and extend return None, and dict, where dict.update returns None.)

Still, returning self is convenient for chaining method calls, even if some Pythonistas don't like it. See kindall's answer in Should internal class methods returnvalues or just modify instance variables in python? for example.

Edit to add some examples based on comment:

What you "should" return—or raise an exception, in which case, "what exception"—depends on the problem. Do you want send_message() to wait for a response, validate that response, and verify that it was good? If so, do you want it to raise an error if there is no response, the validation fails, or the response was valid but says "message rejected"? If so, do you want different errors for each failure, etc? One reasonable (for some value of reasonable) method is to capture all failures with a "base" exception, and make each "type" of failure a derivative of that:

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

Now some of your functions might look something like this (note, none of this is tested):

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)

Then you need some "internal" functions like these:

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

You might choose not to translate socket.errors at all, and not have all your own errors; perhaps you can squeeze your errors into ValueError and KeyError and so on, for instance.

These choices are what programming is all about!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值