stylistic question -- optional return value
Bengt Richter
bokr at oz.net
Mon Sep 2 00:58:46 EDT 2002
On Thu, 29 Aug 2002 13:37:26 GMT, Andrew Koenig <ark at research.att.com> wrote:
>Roy> It's also virtually always true that the real way to speed up a
>Roy> program is not code tweaking, but using better algorithms.
>
>Like most generalizations, this one is not always true.
>
>Remember, we're talking here about an interface decision, which
>means that changing it after the fact is difficult. Moreover,
>this particular program is going to involve a large number of recursive
>function calls, every one of which will use this mechanism to pass
>information back to its caller. In this case, therefore, the choice
>of interface will have a substantial effect on the execution speed
>of the whole program, and it will be difficult to change it later.
>
>In such circumstances, a factor of three is too much to ignore. I am
>not saying that the faster interface is always the right one, but I am
>saying that when there's a large speed difference, and the decision
>will be difficult to change later, then there had better be a
>substantial argument in favor of the slower alternative. Which
>I don't think there is in this case.
>
If added information is the exception (;-) rather than the rule, you might
want to consider using an exception to return the unusual bag of data.
try: is supposed to be low overhead, and the payoff is a clean main path
of excution, using the retval as-is normally, without having to test or
index into a tuple etc., and without having to pack a tuple for a normal
return value from the routine. You can define your own exception and raise it
with an arbitrary set of args, e.g.,
>>> class MyExceptionalData(Exception):
... pass
...
>>> try:
... raise MyExceptionalData('x value', 'optional y')
... except MyExceptionalData, mxd:
... print mxd
...
('x value', 'optional y')
>>> mxd
<__main__.MyExceptionalData instance at 0x007A2460>
>>> dir(mxd)
['__doc__', '__getitem__', '__init__', '__module__', '__str__', 'args']
>>> mxd.args
('x value', 'optional y')
>>> mxd[0]
'x value'
>>> mxd[1]
'optional y'
You could also give your exception class an __init__ function to set
instance attributes and whatever else you'd like.
Anyway, your code might look something like
try: # try overhead only
x = foo() # use x knowing single return value assumption is ok
except MyExceptionalData, e:
x, y = e.args # use x and y according to the exceptional situation
or alternatively
try: # try overhead only
x = foo() # use x knowing single return value assumption is ok
except MyExceptionalData, e:
x, y = e.args
# use y here according to the exceptional situation
# use x here either way
as opposed to something like
x = foo()
if x[1] is not sentinel: # big index + test overhead in normal path
x = x[0] # indexing overhead in normal path
# use single value
else:
x, y = x # same overhead as with e.args less .args attribute lookup
# use the unusual combo
Regards,
Bengt Richter
More information about the Python-list
mailing list