代码之家  ›  专栏  ›  技术社区  ›  Andrey Cizov

Python在子级中重写classmethod

  •  4
  • Andrey Cizov  · 技术社区  · 8 年前

    我正在编写一个过于简单的ORM,它要求我重写子类中的方法。根据上下文的不同,我希望通过类方法或实例方法访问模型,因此我不能简单地重写它们。我相信这段代码很好地描述了这个问题:

    class A:
        @classmethod
        def key_fn(cls, id):
            raise NotImplementedError('')
    
        @classmethod
        def load_all(cls):
            yield from db_fetch_prefix(cls.key_fn('')):
    
    class B(A):
        @classmethod
        def key_fn(cls, id):
            return f'/keys/{id}'
    
    # how do I make sure B.key_fn is called here?
    B.load_all()
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   dnswlt    8 年前

    你的 B.key_fn 确实会被称为。但是你的 load_all 返回生成器,因为您让它 yield from db_fetch_prefix . 您可以通过运行 print(B.load_all()) 最后。输出将为:

    python .\clsss.py
    <generator object A.load_all at 0x0521A330>
    

    我不知道你想通过使用 yield from . 但显示子类中classmethods重写是可能的示例如下:

    class A:
        @classmethod
        def key_fn(cls, id):
            raise NotImplementedError('')
    
        @classmethod
        def load_all(cls):
            return cls.key_fn('foo')
    
    class B(A):
        @classmethod
        def key_fn(cls, id):
            return f'/keys/{id}'
    
    print(B.load_all())  # prints "/keys/foo"
    

    疯狂猜测您想要应用 key_fn 到生成器生成的每个项目 db_fetch_prefix (缩写为 fetch 下),下面的代码显示 B、 键\u fn 也将在有发电机的情况下使用。

    def fetch(callback):
        for i in range(5):  # fake DB fetch
            yield callback(i)
    
    class A:
        @classmethod
        def key_fn(cls, id):
            raise NotImplementedError('')
    
        @classmethod
        def load_all(cls):
            yield from fetch(cls.key_fn)
    
    class B(A):
        @classmethod
        def key_fn(cls, id):
            return f'/keys/{id}'
    
    print(list(B.load_all()))  # prints ['/keys/0', '/keys/1', '/keys/2', '/keys/3', '/keys/4']
    
    推荐文章