determining the number of output arguments
Peter Otten
__peter__ at web.de
Tue Nov 16 03:47:46 EST 2004
Darren Dale wrote:
> I want to extend the capabilities of an existing function without breaking
> backward compatibility. I used nargin and nargout (number of arguments in
> and out) pretty extensively in Matlab.
Here is another alternative to achieve backward compatibility:
class Result(object):
def __init__(self, a, b, c, d):
self.a = a
self.b = b
self.c = c
self.d = d
def __iter__(self):
yield self.a
yield self.b
yield self.c
def old():
return 1, 2, 3
def new():
return Result(1, 2, 3, 4)
# the old function
a, b, c = old()
print a, b, c
# the new function, called by old code
a, b, c = new()
print a, b, c
# the new function, called by new code
r = new()
print r.a, r.b, r.c, r.d
If old code doesn't always immediately unpack, you can implement
__getitem__(), too, or subclass tuple:
class Result(tuple):
def __new__(cls, *items):
items = list(items)
if len(items) == 3:
d = None
elif len(items) == 4:
d = items[-1]
items = items[:-1]
else:
raise ValueError
result = tuple.__new__(cls, items)
result.d = d
return result
a = property(lambda self: self[0])
b = property(lambda self: self[1])
c = property(lambda self: self[2])
In effect you are switching to an object-oriented interface while staying
compatible with old code. This makes future updates a breeze, e. g. if the
calculation of d is costly you could defer it until really needed:
class Result(object):
...
d = property(lambda self: max(self.a, self.b, self.c) + 42)
Peter
More information about the Python-list
mailing list