简体   繁体   中英

Instantiate subclass from superclass

I need to instantiate a subclass from the superclass.

class Superclass(object):
    @staticmethod
    def get_instance():
        #This should return an instance of subclass1 or subclass2

class Subclass1(Superclass):
    pass
class Subclass2(Superclass):
    pass

I want to write:

Subclass1.get_instance()

and obtain an instance of Subclass1, and same for Subclass2

use @classmethod instead of @staticmethod :

class Superclass(object):
    @classmethod
    def get_instance(cls):
        #This should return an instance of subclass1 or subclass2
        return cls()

class Subclass1(Superclass):
    pass
class Subclass2(Superclass):
    pass

If you want to access the list of subclasses of a given class you can use the __subclasses__ method:

>>> class MyClass(object):
...     pass
... 
>>> class Subclass1(MyClass):
...     pass
... 
>>> class Subclass2(MyClass):
...     pass
... 
>>> MyClass.__subclasses__()
[<class '__main__.Subclass1'>, <class '__main__.Subclass2'>]

If you already know the existing subclasses you can simply instantiate them directly:

>>> class MyClass(object):
...     def getInstance(self):
...             return Subclass1()
... 
>>> class Subclass1(MyClass): pass
... 
>>> MyClass().getInstance()
<__main__.Subclass1 object at 0x1e72d10>

Anyway, I guess that you are trying to implement the Singleton pattern, in which case I think you should not use a getInstance method at all. Just implement it using:

  • a module, since modules are singletons
  • Reimplementing __new__ to return the old instance, if an instance already exist
  • Using some metaclass

And there are a lot more ways of doing this.

If this is not your aim, then maybe you ought to change design because super-class usually do not have to know about subclasses.

The correct way to do this, if you cannot just call selfclass() in a classmethod, is to define (or assume) a factory method, and have your superclass method call that factory method on self :

class Mixinator(object):

      @classmethod # this is not really necessary, but it means you don't need an instance to start with
      def factoryuser(selfclass, *args):
          return selfclass.factory(*args)


      #only define factory if you want Mixinator to be usable on its own
      @classmethod
      def factory(selfclass, *args):
          return selfclass(*args)  # this is a stub.

Obviously, child classes should need to have something more involved in their factory to make this worthwhile. I'm not sure there's any use-case that can't be solved by replacing factory with an appropriate __new__ , but this is more explicit.

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