【问题标题】:Is there some mechanism to enforce nested interfaces are implemented in abstract classes in Python?是否有某种机制可以强制在 Python 的抽象类中实现嵌套接口?
【发布时间】:2020-05-03 23:09:58
【问题描述】:

我想创建一个包含一些嵌套类的类,该类在 Python 中定义了一些合同。一个站得住脚的例子是一个类型化的配置对象。我的尝试如下:

from typing import Mapping
from abc import ABCMeta, abstractmethod

class BaseClass(metaclass=ABCMeta):
    # If you want to implement BaseClass, you must also implement BaseConfig
    class BaseConfig(metaclass=ABCMeta):
        @abstractmethod
        def to_dict(self) -> Mapping:
            """Converts the config to a dictionary"""

但不幸的是,我可以在不实现BaseConfig 的情况下实例化BaseClass 的子类:

class Foo(BaseClass):
    pass

if __name__ == "__main__":
    foo = Foo()

有没有办法强制子类也必须实现内部类?

【问题讨论】:

  • 据我所知,abc 不支持此功能。嵌套类不是 Python 中的常见模式。我的建议是把课程拉到模块级别开始......
  • 这正是我所期望的。非常令人失望。
  • 您有什么特别的原因要使用嵌套类吗?
  • 出于同样的原因,您将在基类中定义对abstractmethods 进行操作的方法:因此您可以在更高的抽象级别上进行操作。如果例如配置是在模块级别定义的,我不能这样做。
  • 你能详细说明一下吗?确切地说,在模块级别定义的另一个类不能做什么?它看起来就像存在于另一个类的命名空间中的类一样抽象......

标签: python inner-classes abc


【解决方案1】:

目前看来这是不可能的。最接近的就是创建两个抽象类(对应外部类和内部类)并强制实现者为具体内部类提供cls构造函数;例如:

from abc import ABCMeta, abstractmethod

class Inner(metaclass=ABCMeta):
    @abstractmethod
    def __str__(self):
        pass

class Outer(metaclass=ABCMeta):
    inner_cls = Inner

    def shout(self, *args, **kwargs):
        inner = self.inner_cls(*args, **kwargs)
        print(f"My inner is {inner}!!!")

class FooInner(Inner):
    def __str__(self):
        return "FooInner"

class FooOuter(Outer):
    inner_cls = FooInner

这要求Inner 至少有一个abstractmethod,否则可以将其实例化为默认的inner_cls 实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-08
    • 2015-04-11
    • 1970-01-01
    • 1970-01-01
    • 2012-09-02
    • 1970-01-01
    • 1970-01-01
    • 2011-01-08
    相关资源
    最近更新 更多