I wanna to make my code look nicer.
Example:
result = somefunction()
if result == what_i_need:
do_something()
else:
print 'that\'s not what i need', result
I'm trying to make something like this:
if somefunction() == what_i_need:
do_something()
else:
print 'that\'s not what i need', <return value of somefunction>
Is this possible?
Here's something you could technically try, but shouldn't:
def somefunction():
val = 3 # calculate value
globals()['somefunction_return'] = val # store it in globals() first
return val # return as normal
def do_something():
print 'got it'
what_i_need = 3
if somefunction() == what_i_need:
do_something()
print 'that\'s not what i need', somefunction_return
# result:
#
# got it
# that's not what i need 3
Why shouldn't you do this?
The assignment is still happening somewhere else, so all its done is sweep the unwanted code out of the way. Pay no attention to the garbage behind the curtain.
Messing with globals() is more fragile than a simple assignment done in the way you're already doing it, partly because it's more difficult for the developer to avoid tripping over it.
It introduces something called "side effects," extra events that a function does without saying so. In this example, somefunction is doing something in addition to its planned purpose, without advertising as much. This makes code much harder to maintain.
It makes the code more difficult to read and follow, which goes against the intent of Python. Imagine that someone is reading the if structure above. How are they supposed to know where somefunction_return came from? They would have to look through every line of code until they found the offending side effect in somefunction. We might have even named it something else, like my_foobar_value, and then the reader wouldn't even have a hint that they should check somefunction.
Please continue to use the ordinary assignment you already have in place.
No, the only sensible way to capture a function's return value in Python is to explicitly assign it to a variable.
Even if there was a device for referring to a previous function's return value through implicit means, Python culture abhors this sort of thing. One oft-cited Python principle is "explicit is better than implicit".
Related
I often have to execute some function, save the output, and depending on what the output was, do different things. And then later on use the output as input to more functions.
It results in a very specific pattern of code.
I feel like I'm missing something simple.
... as if some logic here could be somehow streamlined. The variable declaration, variable checking, and forthcoming execution of other stuff onto said variable seems almost redundant.
(tried to make the code as applicable to everyone and as applicable to every application, as possible)
here's some sample code that fits this predicament:
some_sort_of_data=validate(var1, 'type1')
if some_sort_of_data.is_bad:
return some_sort_of_data.is_bad
more_data=validate(var2, 'type2')
if more_data.is_bad:
return more_data.is_bad
get_special_info=get_parent_of_item(some_sort_of_data.validated_item)
if get_special_info['error']:
return get_special_info['data']
if not (has_access_rights() or
special_relationship(more_data.validated_item) or
some_sort_of_other_permissions(get_special_info['result'])):
return "Blah Blah blah some sort of incompatibility"
new_status_result=change_status(some_sort_of_data.validated_item, more_data.validated_item)
if new_status_result['error']
return new_status_result['result']
# If we've passed all the previous checks and managed to get all the way here..
return "yay did a thing successfully"
... is it just me or do you also see how such a pattern feels off? If so, how can it best be streamlined?
edit: I know in some other languages you can streamline it a bit by writing
if (some_sort_of_data=validate(var1, 'type1')=="success")
return some_sort_of_data.some_class_variable
instead of
some_sort_of_data=validate(var1, 'type1')
if some_sort_of_data=="success":
return some_sort_of_data.some_class_variable
but that's still not enough and still quite redundant, right?
I'm learning Python and, so far, I absolutely love it. Everything about it.
I just have one question about a seeming inconsistency in function returns, and I'm interested in learning the logic behind the rule.
If I'm returning a literal or variable in a function return, no parentheses are needed:
def fun_with_functions(a, b):
total = a + b
return total
However, when I'm returning the result of another function call, the function is wrapped around a set of parentheses. To wit:
def lets_have_fun():
return(fun_with_functions(42, 9000))
This is, at least, the way I've been taught, using the A Smarter Way to Learn Python book. I came across this discrepancy and it was given without an explanation. You can see the online exercise here (skip to Exercize 10).
Can someone explain to me why this is necessary? Is it even necessary in the first place? And are there other similar variations in parenthetical syntax that I should be aware of?
Edit: I've rephrased the title of my question to reflect the responses. Returning a result within parentheses is not mandatory, as I originally thought, but it is generally considered best practice, as I have now learned.
It's not necessary. The parentheses are used for several reason, one reason it's for code style:
example = some_really_long_function_name() or another_really_function_name()
so you can use:
example = (some_really_long_function_name()
or
another_really_function_name())
Another use it's like in maths, to force evaluation precede. So you want to ensure the excute between parenthese before. I imagine that the functions return the result of another one, it's just best practice to ensure the execution of the first one but it's no necessary.
I don't think it is mandatory. Tried in both python2 and python3, and a without function defined without parentheses in lets_have_fun() return clause works just fine. So as jack6e says, it's just a preference.
if you
return ("something,) # , is important, the ( ) are optional, thx #roganjosh
you are returning a tuple.
If you are returning
return someFunction(4,9)
or
return (someFunction(4,9))
makes no difference. To test, use:
def f(i,g):
return i * g
def r():
return f(4,6)
def q():
return (f(4,6))
print (type(r()))
print (type(q()))
Output:
<type 'int'>
<type 'int'>
This question already has answers here:
It is more efficient to use if-return-return or if-else-return?
(9 answers)
Closed 8 years ago.
I'm getting to this question again from time to time. Is there a general answer on this?
If there is a single if-else construct and the if section has a continue, break or return in it, should it be followed by an else for readability or some reasons?
if v == 0:
continue # / break / return
else: # is this necessary?
...
Semantically, there is no requirement put the ... inside an else clause. Whether or not you do is largely a matter of personal preference.
When I am thinking about how to structure code like this, there are competing considerations. On the one hand, I like to keep the number of nesting levels to a minimum. On the other, I try to use break and continue in moderation, since to my eye they make the flow of control somewhat harder to follow.
For these reasons, I would almost never use the form shown in your question. Instead, I would write either
if v == 0:
continue
# ...
or
if v != 0:
# ...
I would generally prefer the latter to the former. The choice largely depends on how much code there is in the # ... block (which, as a rule of thumb, I would try to keep to a minimum).
It may not be necessary, but it's a good idea in my opinion because
Explicit is better than implicit (The Zen of Python, Tim Peters)
Readability counts (ibid.)
and the indented blocks make it obvious what you want to happen when the condition is True or False.
if foo:
do_this()
break
else:
do_that()
Here, do_this() and do_that() are "on the same level". In my opinion, that looks nicer than
if foo:
do_this()
break
do_that()
Yes.
one:
for readability.
two:
It can help you debug your application. Assume that you have a block of code where the if statement doesn't need an else block and the else block doesn't make any sense and should never be hit.
You can always put a print statement in there or call the error message code to catch possible bad data operations.
I hope this helps.
Edit : I think this depends on the context of the usage where we are using the if-else construct. But however for readability , understandability it is better to use else.
The question is in the title...
I'm in a process of learning Python and I've heard a couple of times that function returning None is something you never should have in a real program (unless your function never returns anything). While I can't seem to find a situation when it is absolutely necessary, I wonder if it ever could be a good programming practice to do it. I.e., if your function returns integers (say, solutions to an equation), None would indicate that there is no answer to return. Or should it always be handled as an exception inside the function? Maybe there are some other examples when it is actually useful? Or should I never do it?
This just flat-out isn't true. For one, any function that doesn't need to return a value will return None.
Beyond that, generally, keeping your output consistent makes things easier, but do what makes sense for the function. In some cases, returning None is logical.
If something goes wrong, yes, you should throw an exception as opposed to returning None.
Unfortunately, programming tends to be full of advice where things are over-generalized. It's easy to do, but Python is pretty good with this - practicality beats purity is part of the Zen of Python. It's essentially the use case for dict.get() - in general, it's better to throw the exception if a key isn't found, but in some specific cases, getting a default value back is more useful.
def abc():
print 1
return None
print 2
is the same as
def abc():
print 1
return
print 2
or even
def abc():
print 1
All functions that don't return something return None. One very important use case of returning None is when you want to say "terminate this function" without having to nest a bunch of ifs.
It's a little complicated.
It comes down to cases here:
A function that merely mutates its object's state doesn't return anything (returns None). For example, given a list called L: L.sort(); L.append("joe")
Other functions create a new object or a new copy of an object, and return it without mutating the original list. Consider: sorted(L) ; y = L + [1,2,3]
It's generally bad form to return None meaning "everything is fine."
If you have some kind of lookup/accessor, None means "the value of that item is None", and when it's not found you should throw the appropriate exception.
In most other cases, returning None is a little confusing.
Is there a pythonic preferred way to do this that I would do in C++:
for s in str:
if r = regex.match(s):
print r.groups()
I really like that syntax, imo it's a lot cleaner than having temporary variables everywhere. The only other way that's not overly complex is
for s in str:
r = regex.match(s)
if r:
print r.groups()
I guess I'm complaining about a pretty pedantic issue. I just miss the former syntax.
How about
for r in [regex.match(s) for s in str]:
if r:
print r.groups()
or a bit more functional
for r in filter(None, map(regex.match, str)):
print r.groups()
Perhaps it's a bit hacky, but using a function object's attributes to store the last result allows you to do something along these lines:
def fn(regex, s):
fn.match = regex.match(s) # save result
return fn.match
for s in strings:
if fn(regex, s):
print fn.match.groups()
Or more generically:
def cache(value):
cache.value = value
return value
for s in strings:
if cache(regex.match(s)):
print cache.value.groups()
Note that although the "value" saved can be a collection of a number of things, this approach is limited to holding only one such at a time, so more than one function may be required to handle situations where multiple values need to be saved simultaneously, such as in nested function calls, loops or other threads. So, in accordance with the DRY principle, rather than writing each one, a factory function can help:
def Cache():
def cache(value):
cache.value = value
return value
return cache
cache1 = Cache()
for s in strings:
if cache1(regex.match(s)):
# use another at same time
cache2 = Cache()
if cache2(somethingelse) != cache1.value:
process(cache2.value)
print cache1.value.groups()
...
There's a recipe to make an assignment expression but it's very hacky. Your first option doesn't compile so your second option is the way to go.
## {{{ http://code.activestate.com/recipes/202234/ (r2)
import sys
def set(**kw):
assert len(kw)==1
a = sys._getframe(1)
a.f_locals.update(kw)
return kw.values()[0]
#
# sample
#
A=range(10)
while set(x=A.pop()):
print x
## end of http://code.activestate.com/recipes/202234/ }}}
As you can see, production code shouldn't touch this hack with a ten foot, double bagged stick.
This might be an overly simplistic answer, but would you consider this:
for s in str:
if regex.match(s):
print regex.match(s).groups()
There is no pythonic way to do something that is not pythonic. It's that way for a reason, because 1, allowing statements in the conditional part of an if statement would make the grammar pretty ugly, for instance, if you allowed assignment statements in if conditions, why not also allow if statements? how would you actually write that? C like languages don't have this problem, because they don't have assignment statements. They make do with just assignment expressions and expression statements.
the second reason is because of the way
if foo = bar:
pass
looks very similar to
if foo == bar:
pass
even if you are clever enough to type the correct one, and even if most of the members on your team are sharp enough to notice it, are you sure that the one you are looking at now is exactly what is supposed to be there? it's not unreasonable for a new dev to see this and just fix it (one way or the other) and now its definitely wrong.
Whenever I find that my loop logic is getting complex I do what I would with any other bit of logic: I extract it to a function. In Python it is a lot easier than some other languages to do this cleanly.
So extract the code that just generates the items of interest:
def matching(strings, regex):
for s in strings:
r = regex.match(s)
if r: yield r
and then when you want to use it, the loop itself is as simple as they get:
for r in matching(strings, regex):
print r.groups()
Yet another answer is to use the "Assign and test" recipe for allowing assigning and testing in a single statement published in O'Reilly Media's July 2002 1st edition of the Python Cookbook and also online at Activestate. It's object-oriented, the crux of which is this:
# from http://code.activestate.com/recipes/66061
class DataHolder:
def __init__(self, value=None):
self.value = value
def set(self, value):
self.value = value
return value
def get(self):
return self.value
This can optionally be modified slightly by adding the custom __call__() method shown below to provide an alternative way to retrieve instances' values -- which, while less explicit, seems like a completely logical thing for a 'DataHolder' object to do when called, I think.
def __call__(self):
return self.value
Allowing your example to be re-written:
r = DataHolder()
for s in strings:
if r.set(regex.match(s))
print r.get().groups()
# or
print r().groups()
As also noted in the original recipe, if you use it a lot, adding the class and/or an instance of it to the __builtin__ module to make it globally available is very tempting despite the potential downsides:
import __builtin__
__builtin__.DataHolder = DataHolder
__builtin__.data = DataHolder()
As I mentioned in my other answer to this question, it must be noted that this approach is limited to holding only one result/value at a time, so more than one instance is required to handle situations where multiple values need to be saved simultaneously, such as in nested function calls, loops or other threads. That doesn't mean you should use it or the other answer, just that more effort will be required.