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