idiom for constructor?
Terry Hancock
hancock at anansispaceworks.com
Wed Jun 1 17:07:15 EDT 2005
On Wednesday 01 June 2005 12:50 pm, Mac wrote:
> Is there a nice Python idiom for constructors which would expedite the
> following?
>
> class Foo:
> def __init__(self, a,b,c,d,...):
> self.a = a
> self.b = b
> self.c = c
> self.d = d
> ...
>
> I would like to keep the __init__ parameter list explicit, as is,
> rather than passing in a dictionary, as I want the code to be explicit
> about what arguments it expects... in effect enforcing the right number
> of arguments.
Well, it's hard to automate it and keep the parameter list explicit,
but you could do this, of course:
class Foo:
def __init__(self, *args):
maps = zip(('a','b','c','d'), args[:4])
for map in maps:
setattr(self, map[0], map[1])
Which *will* limit the arguments to the ones specified. As an additional
tweak, you could make this a base class and put the argument list in
the subclass to hide the magic:
class Args:
argspec = ()
def __init__(self, *args):
maps = zip(self.argspec, args[:len(self.argspec)])
for map in maps:
setattr(self, map[0], map[1])
class Foo(Args):
argspec = ('a', 'b', 'c', 'd')
Or even better, use a method, so you can customize:
class Args:
argspec = ()
def _get_args(self, *args):
maps = zip(self.argspec, args[:len(self.argspec)])
for map in maps:
setattr(self, map[0], map[1])
class Foo(Args):
argspec = ('a', 'b', 'c', 'd')
def __init__(self, *args):
self._get_args(*args)
This version silently ignores extra arguments, but you might
want to raise an exception instead:
class Args:
argspec = ()
def _get_args(self, *args):
expected = len(self.argspec)
given = len(args)
if expected != given:
raise TypeError("__init__ takes exactly %d arguments (%d given)" % (expected, given))
maps = zip(self.argspec, args[:expected])
for map in maps:
setattr(self, map[0], map[1])
Using this, I get the following response to too many arguments:
>>> g = Foo(1, '3', 4.0, 'spam', 'eggs') Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 4, in __init__
File "<stdin>", line 7, in _get_args
TypeError: __init__ takes exactly 4 arguments (5 given)
HTH
Cheers,
Terry
--
Terry Hancock ( hancock at anansispaceworks.com )
Anansi Spaceworks http://www.anansispaceworks.com
More information about the Python-list
mailing list