【问题标题】:Python: How to subclass while calling parent class?Python:如何在调用父类时进行子类化?
【发布时间】:2018-11-19 23:10:23
【问题描述】:

我有以下正在被子类化的类:

class ConnectionManager(object):

    def __init__(self, type=None):

        self.type = None

        self.host = None
        self.username = None
        self.password = None
        self.database = None
        self.port = None


    def _setup_connection(self, type):
        pass

然后我有一个特定的管理器来管理各种数据库。我可以这样称呼它们:

c = MySQLConnectionManager()
c._setup_connection(...)

但是,有没有办法改为执行以下操作?

c = ConnectionManager("MySQL")
c._setup_connection(x,y,z) # this would call the MySQLConnectionManager, 
                           # not the ConnectionManager

基本上,我希望能够以相反的顺序调用事物,这可能吗?

【问题讨论】:

  • 也许您应该实现__new__() - 它允许您根据传递的参数创建并返回适当子类的实例。 __init__() 来不及做任何这样的事情,对象已经被创建了。
  • @jasonharper 能否请您说明一下如何在上面完成?
  • @jasonharper 我会在__new__ 方法中返回什么?会是return MySQLConnectionManager() 吗?

标签: python python-3.x subclassing


【解决方案1】:

一种方法是使用静态工厂方法模式。为简洁起见,省略不相关的代码:

class ConnectionManager:
    # Create based on class name:

    @staticmethod
    def factory(type):
        if type == "mysql": return MySqlConnectionManager()
        if type == "psql": return PostgresConnectionManager()
        else:
            # you could raise an exception here
            print("Invalid subtype!")

class MySqlConnectionManager(ConnectionManager):
    def connect(self): print("Connecting to MySQL")

class PostgresConnectionManager(ConnectionManager):
    def connect(self): print("Connecting to Postgres")

使用工厂方法创建子类实例:

psql = ConnectionManager.factory("psql")
mysql = ConnectionManager.factory("mysql")

然后根据需要使用您的子类对象:

psql.connect()  # "Connecting to Postgres"
mysql.connect()  # "Connecting to MySQL" 

【讨论】:

  • 谢谢,这似乎是最简单的方法。出于好奇,使用这种方法和使用 __new__() 项目有什么区别?
  • 另外,factory = staticmethod(factory) 行是做什么的?
  • @HenryH 更新为使用staticmethod 装饰器,它允许我们从未实例化的对象调用装饰方法factory
  • 类不需要显式继承自python 3中的对象。
  • @HenryH 使用静态工厂方法而不是构造函数 (__new__) 有几个很好的理由 - 一个重要的区别是静态工厂方法可以有意义地命名。
猜你喜欢
  • 2016-02-20
  • 1970-01-01
  • 2016-08-23
  • 1970-01-01
  • 1970-01-01
  • 2020-08-10
  • 2018-06-23
  • 1970-01-01
  • 2012-10-28
相关资源
最近更新 更多