Generic constructors and duplication of internal Python logic

John J. Lee jjl at pobox.com
Mon Apr 19 17:53:14 EDT 2004


Peter Otten <__peter__ at web.de> writes:

> John J. Lee wrote:
[...]
> You could use a noop method check_attrs() to define the argspec.
> check_attrs() is then called from the mixin's __init__() just to check that
> the parameters comply.
> 
> import inspect
> 
> def make_attrspec(f):
>     a = inspect.getargspec(f)
>     names = a[0]
>     if names[0] in ["self", "cls"]:
>         # XXX for now relies on naming convention
>         del names[0]
>     defaults = a[3]
>     for i in range(-1, -len(defaults)-1, -1):
>         names[i] = names[i], defaults[i]
>     return names
> 
> class ArgsMixin:
>     def __init__(self, *args, **kwds):
>         self.check_attrs(*args, **kwds)
> 
> class Blah(ArgsMixin):
>     def check_attrs(self, foo, bar, baz, optional1="first",
> optional2="second"):
>         pass
>     attr_spec = make_attrspec(check_attrs)

Clever.  But how to get __init__ to assign the arguments to the
instance?

b = Blah(foo=1, bar=2, optional1=4)
assert b.foo, b.bar, b.optional1 = 1, 2, 4


That half of the problem is missing in your solution.

[...]
> Todo: automagically "normalize" the argument list, e. g. convert
> Blah(1, 2, optional1="o1", baz=99) to Blah(1, 2, 99, optional1="o1").

As long as baz ends up getting assigned the value 99 and optional1
gets the value "o1", I don't care how that's achieved (except that I'd
like it done without having to write out all the logic as I have ATM
-- I want to reuse Python's own internal knowledge of argument lists
to get my attributes assigned).


> A workaround would be to make them all keyword arguments
> 
> kwds.update(dict(zip(Blah.attr_spec, args))) 
> 
> after the self.check_attrs() call.

Not acceptable in my case.


John



More information about the Python-list mailing list