如何自动添加基类?

2024-10-17 12:18:38 发布

您现在位置:Python中文网/ 问答频道 /正文

简介:包xy定义了一个Node类(名称不是真实的)。多个节点创建了一个类似于图形的结构,包可以用它做有趣的事情。基本示例:

node0 = xy.Node(... some arguments here ...)

节点可以具有可选功能。这目前是通过附加组件/混合类实现的。诸如此类:

class NodeF7(xy.Feature7, xy.Node):
    pass

node1 = NodeF7(..., feature7_timeout=5)
  1. 软件包用户现在可以指定与功能7相关的值
  2. 包本身允许在其内部代码中调用特性的方法,因为isinstance(node1, xy.Feature7)test为true

问题:通常需要定义一个新类来创建它的单个实例。我正在考虑将用法简化为:

node1 = xy.Node(..., feature7_timeout=5)

也就是说,当Node类遇到任何与feature7相关的参数时,它应该自动包含Feature7类附加组件。重要的是isinstance(node1, xy.Feature7)成为现实

我想问,如何在一揽子计划中实施这一点。这个有设计模式吗

  • 我确信类工厂函数可以工作,但是
  • 也许一些与抽象基类(ABC)相关的技巧可以优雅地解决这个问题
  • 或者__new__函数中的一些聪明代码

Tags: 函数代码功能名称node节点定义timeout
1条回答
网友
1楼 · 发布于 2024-10-17 12:18:38

首先,我们准备一种注册特征的方法

feature_registry = {}


def register_feature(*parameters):
    def decorator(cls):
        for parameter in parameters:
            feature_registry[parameter] = cls
        return cls
    return decorator


@register_feature('feature7_timeout')
class Feature7:
    def __init__(self, *args, feature7_timeout=None, **kwargs):
        print('feature7_timeout:', feature7_timeout)

    def feature7(self):
        assert isinstance(self, Feature7)

然后,在__new__函数中,我们获得要素类并创建一个新类型

class Node:

    def __new__(cls, *args, **kwargs):
        feature_classes = {feature_registry.get(k) for k in kwargs}
        feature_classes.discard(None)
        cls = type(cls.__name__, (*feature_classes, cls), {})
        return super().__new__(cls)

用法:

node1 = Node(feature7_timeout=5)
node1.feature7()

相关问题 更多 >