loading...

Best practice for Python returns

github logo ・1 min read

Hi.
I have a function that should return the result of a query.
It works, but my question is related to what is the best practise.

The return value in this case is a response object from an API, that contains a value which indicate whether the query failed or not. The first question then is, should I have my function return the result of the query as it is?

For the cases where the return object says nothing about how the execution of the function went, should it also return a boolean to indicate if things went as it should?

And lastly, if I would need to return more than one variable, should they be returned as a tuple, a dictionary, or in some other way?

I haven't been programming with Python for long. I know a bit, but I lack a lot of knowledge about how to write good/nice code.

twitter logo DISCUSS (5)
markdown guide
 

In most cases, the 'de-facto' standard for Python is:

  • If the function worked, return the result if there is one, otherwise return nothing (unless the below point applies to some possibilities, in which case return True).
  • If the function ran into an issue that the caller is supposed to be watching for which is not potentially fatal, return something distinct from a valid result to indicate that.
  • If the function ran into some actually fatal error, throw an appropriate exception (ideally not one of the generic ones unless it's something that truly is an exact match like a type or value error in the parameters) instead of returning anything.

For complex return values:

  • Tuples are usually used for structured data with a fixed number of fields each having a pre-defined purpose (for example, representing a date as a tuple with each field of the date individually accessible), or when you specifically need to return an immutable sequence (which is rare in Python). Note that returning a tuple implies to many people that you will always be returning a tuple of the same size.
  • For simple groups of return values, lists are the norm, though you may also see deques, generators, or custom sequence classes used on occasion. The important thing though is that the result is iterable, because that's usually what the caller is going to want to do with it.
  • In some rare cases, a Set may be returned for a collection of return values, but this is typically only used in cases where the whole API is dealing primarily with sets of values.
  • Dictionaries and other mapping types are only used for structured data or to directly replicate API's that return structured data.

Regardless, the most important thing here is to make your code consistent. Pick an approach and stick to it. I would encourage you to look at some of the bigger projects written in Python for ideas on this though.

 

Thank you for such a in depth reply :D
I'll have to read this a few times, and look up some things I have not encountered in Python before :)
Looking forward to testing out what you have suggested, and I will try to stay consistent in my projects to come.

 

I dont know much about python, but when building graphql api, after long trial and error we went with structure like this:

{
  "errors": {},
  "results": {}
}

Errors is empty when there are no errors, and populated when something went wrong. We found out that it is easier to handle both cases when return values are consistent.

 

Hi, and thanks for the reply :)
Yeah, I was thinking of using a dictionary in a similar fashion, where one key-value pair is used to indicate if there was any trouble or not.

Having a key error seems like a nice way to create the necessary feed back in a standardized way.

 

this is preferable

try:
   data = get_one({"name":"joe"})

except ConnectionError:
   # handle a ConnectionError

else:
   # if no exceptions were raised then the data is presumed to be good
   do_something_with(data)
Classic DEV Post from May 1 '19

Build a 💣 Bomb-Diggity Technical Presentation (🎤 Mic Drop Optional)

The steps and process behind building a great technical presentation.

joakimRN profile image
Mostly interested in Python, databases (MariaDB & Elasticsearch). Back-end stuff. Maybe Java/Kotlin or C++ later :)