Generic constructors and duplication of internal Python logic

Peter Otten __peter__ at web.de
Fri Apr 23 03:56:45 EDT 2004


John J. Lee wrote:

[my buggy code]

> This can be fixed, but then we move towards my clumsy-but-correct (I
> hope) implementation.  I'm disappointed there's no simple solution
> that makes better use of Python's own knowledge of argument
> specifications.

I warned you that my code was not thoroughly tested, and I aggree with you
that this is getting clumsy. 
But will I stop trying to come up with something better? no way. Here's my
next try, and I'm likely to present something completely different again if
you don't like it - not sure if that's a promise or a threat :-)

import inspect, sys

def generateSource(m):
    a = inspect.getargspec(m)
    names = a[0]
    if a[1] or a[2]:
        raise Execption("*args/**kw not supported")
    nself = names[0]
    assignments = ["    %s.%s = %s" % (nself, n, n) for n in names[1:]]
    return "def %s%s:\n%s" % (m.__name__,
                              inspect.formatargspec(*inspect.getargspec(m)),
                              "\n".join(assignments))

def generateMethod(m):
    """Generate a method with the same signiture
       as m. For every argument arg a corresponding line

       self.arg = arg

       is added.
    """
    # source code generation factored out for easier debugging
    ns = {}
    exec generateSource(m) in ns
    return ns[m.__name__]

class Demo(object):
    def __init__(self, foo, bar, baz=2, bang=3):
        pass
    __init__ = generateMethod(__init__)
    def __str__(self):
        return ", ".join(["%s=%r" % (n, getattr(self, n))
             for n in "foo bar baz bang".split()])

print "--- generatatSource(Demo.__init__) ---"
print generateSource(Demo.__init__)
print "--------------------------------------"

print Demo(1, 2, 3)
print Demo(1, 2)
print Demo(1, 2, bang=99)
print Demo(1, bang=99, bar=11)
print Demo(1, bar=11)

Peter



More information about the Python-list mailing list