简体   繁体   中英

dynamic class with inheritance in python

How can I create classes dynamically in a class? As I tried below, I get a NameError: name 'Foo is not defined. I am quite new to Python, pls forgive me if it's obvious.

class Parent(object):
    name2class = {'foo' : Foo, 'bar' : Bar }

    def do(self,string):
        return name2class[string]()

class Foo(Parent):
    pass

class Bar(Parent):
    pass

if __name__ == '__main__':
    parent = Parent()
    instance = parent.do()

As you've written this, you need to define Foo and Bar above Parent since Parent references the other classes.

Edit: You just need to move those class references into the method:

class Parent(object):
    def do(self,string):
        name2class = {'foo' : Foo, 'bar' : Bar }
        return name2class[string]()

class Foo(Parent):
    pass

class Bar(Parent):
    pass

if __name__ == '__main__':
    parent = Parent()
    instance = parent.do('foo')

Edit2: Here's your factory version:

class Parent(object):
    # Add shared methods here
    pass

class Foo(Parent):
    # Add unique methods
    pass

class Bar(Parent):
    # Add unique methods
    pass

class ParentFactory(object):
    def __init__(self):
        self.name2class = {'foo' : Foo, 'bar' : Bar}

    def create(self, string):
        return self.name2class[string]()

if __name__ == '__main__':
    factory = ParentFactory()
    instance = factory.create('foo')

The classes Foo and Bar were not defined by the time name2class dictionary instantiation needed them. The other bug was no parameter being passed to Parent.do()

class Parent(object):
    def __init__(self):
        self.name2class = {'foo' : Foo, 'bar' : Bar}

    def do(self, string):
        return self.name2class[string]()

class Foo(Parent):
    pass

class Bar(Parent):
    pass

if __name__ == '__main__':
    parent = Parent()
    instance = parent.do('foo')

You can use python type(name, bases, dict) functuion:...

Not Working


OK. Take a look here:

class Parent(object):

        childs = {}
        def somefunc(self):
                print "Hello from, %s"%self

        def do(self, string):

                return self.childs[string]()

class Foo(Parent):

        pass

class Bar(Parent):

        pass

parent = Parent()
parent.somefunc()
parent.childs["foo"] = Foo
parent.childs["bar"] = Bar
foo = parent.do("foo")
foo.somefunc()
bar = parent.do("bar")
bar.somefunc()

Which gives me:

Hello from, <__main__.Parent object at 0x...>
Hello from, <__main__.Foo object at 0x...>
Hello from, <__main__.Bar object at 0x...>

Defining a new child class should not impact the base class implementation. The appropriate design pattern here is the Factory. There are many ways to implement it, from a simple function to a dynamic registration mechanism. The simpler version:

class Parent(object):
   # your code here
   pass

class Child1(Parent):
   # XXX

class Child2(Parent):
   # XXX

class Child2(Parent):
   # XXX


CLSMAP = {
    "name1": Child1,
    "name2": Child2,    
    "name3": Child3,
    }   

def create(name, *args, **kw):
   return CLSMAP[name](*args, **kw)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM