【问题标题】:How to properly inherit class method如何正确继承类方法
【发布时间】:2020-11-13 03:44:08
【问题描述】:

我有一个创建连接池的数据库连接类。现在随着应用程序的增长并且我正在添加不同类型的数据库编写器,我想将数据库连接移动到一个单独的类并从它继承。到目前为止,我有这个:

class ServiceDB:
    @classmethod
    async def init(cls, settings):
        self = ServiceDB()
        self.pool = await asyncpg.create_pool(
            database=settings["POSTGRES_DB"],
            user=settings["POSTGRES_USER"],
            password=settings["POSTGRES_PASSWORD"],
            host=settings["DB_HOST"],
            port=settings["DB_PORT"],
        )
        return self



class ChildWriter(ServiceDB):
    async def write_db(self, query):
        # Write to specific table
        pass



if __name__ == "__main__":
    settings = {'info': "some connection settings"}
    query = "SELECT * FROM 'table'"
    connection = await ChildWriter().init(settings)
    await connection.write_db(msg, query)

当我运行它时,我得到AttributeError: 'ServiceDB' object has no attribute 'write_db'。如何使用write_db 方法正确扩展ServiceDB

【问题讨论】:

    标签: python-3.x inheritance class-method python-class


    【解决方案1】:

    类方法接收“当前类”作为第一个参数。实例化这个cls,而不是固定的基类。

    class ServiceDB:
        @classmethod
        async def init(cls, settings):
            self = cls()  # cls is the *current* class, not just ServiceDB
            self.pool = await asyncpg.create_pool(
                database=settings["POSTGRES_DB"],
                user=settings["POSTGRES_USER"],
                password=settings["POSTGRES_PASSWORD"],
                host=settings["DB_HOST"],
                port=settings["DB_PORT"],
            )
            return self
    

    请注意,理想情况下,所有属性都通过__init__ 而不是单独的classmethod 构造函数设置。单独的构造函数应该只传递外部构造的任何属性。

    class ServiceDB:
        def __init__(self, pool):
            self.pool = pool
    
        @classmethod
        async def init(cls, settings, **kwargs):
            pool = await asyncpg.create_pool(
                database=settings["POSTGRES_DB"],
                user=settings["POSTGRES_USER"],
                password=settings["POSTGRES_PASSWORD"],
                host=settings["DB_HOST"],
                port=settings["DB_PORT"],
            )
            return cls(pool=pool, **kwargs)
    
    class ChildWriter(ServiceDB):
        async def write_db(self, query): ...
    
    if __name__ == "__main__":
        settings = {'info': "some connection settings"}
        query = "SELECT * FROM 'table'"
        # call classmethod on class   V
        connection = await ChildWriter.init(settings)
        await connection.write_db(msg, query)
    

    【讨论】:

    • 太好了,正是我需要的,感谢classmethod 提示
    猜你喜欢
    • 2019-01-15
    • 2018-04-05
    • 2012-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多