python - Python 中的动态子类化

标签 python inheritance dynamic runtime

我正在开发的库中有许多原子类(Components/Mixins,不太确定如何调用它们),它们将被应用程序子类化。创建这种原子性是为了让应用程序只能使用它们需要的特性,并通过多重继承组合组件。

但是,有时无法确保这种原子性,因为某些组件可能依赖于另一个组件。例如,假设我有一个组件可以为对象提供图形表示,另一个组件使用该图形表示来执行一些碰撞检查。第一个是纯原子的,但是后者要求当前对象已经子类化了这个图形表示组件,这样它的方法就可以使用了。这是一个问题,因为我们必须以某种方式告诉这个库的用户,为了使用某个组件,他们还必须继承另一个组件。我们可以使这个碰撞组件成为视觉组件的子类,但是如果用户也将这个视觉组件子类化,它就不会工作,因为类不在同一级别(不像简单的菱形关系,这是需要的),并且会给出程序员难以理解的神秘元类错误。

因此,我想知道是否有任何很酷的方法,通过元类重定义或使用类装饰器,来标记这些非原子组件,当它们被子类化时,额外的依赖将被注入(inject)到当前对象中,如果它尚不可用。示例:

class AtomicComponent(object):
    pass

@depends(AtomicComponent)  # <- something like this?
class UnAtomicComponent(object):
    pass

class UserClass(UnAtomicComponent): #automatically includes AtomicComponent
    pass

class UserClass2(AtomicComponent, UnAtomicComponent): #also works without problem
    pass

有人可以提示我该怎么做吗?或者如果有可能...

编辑: 由于元类解决方案是最好的解决方案是值得商榷的,因此我将在 2 天内不接受它。

其他解决方案可能是改进错误消息,例如,执行类似 UserClass2 的操作会给出一个错误,指出 UnAtomicComponent 已经扩展了该组件。然而,这会产生一个问题,即不可能使用两个 UnAtomicComponents,因为它们会在不同级别上子类化对象。

最佳答案

“元类”

这就是他们的目的!在创建类时,类参数贯穿于 元类代码,例如,您可以在其中检查基础并进行更改。

这运行没有错误——尽管它没有保留所需类的顺序 标有“depends”装饰器:

class AutoSubclass(type):
    def __new__(metacls, name, bases, dct):
        new_bases = set()
        for base in bases:
            if hasattr(base, "_depends"):
                for dependence in base._depends:
                    if not dependence in bases:
                        new_bases.add(dependence)
        bases = bases + tuple(new_bases)
        return type.__new__(metacls, name, bases, dct)



__metaclass__ = AutoSubclass

def depends(*args):
    def decorator(cls):
        cls._depends = args
        return cls
    return decorator


class AtomicComponent:
    pass

@depends(AtomicComponent)  # <- something like this?
class UnAtomicComponent:
    pass

class UserClass(UnAtomicComponent): #automatically includes AtomicComponent
    pass

class UserClass2(AtomicComponent, UnAtomicComponent): #also works without problem
    pass

(我从“object”中删除了继承,因为我声明了一个全局 __metaclass__ 变量。所有类仍然是新样式类并具有这个元类。从对象或另一个类继承确实覆盖了全局__metaclass__变量,类级别__metclass__必须声明)

-- 编辑--

在没有元类的情况下,要走的路是让您的类正确地继承它们的依赖项。 Tehy 将不再是那个“原子”,但是,由于它们不能作为那个原子工作,所以可能无关紧要。

在下面的示例中,类 C 和 D 将是您的用户类:

>>> class A(object): pass
... 
>>> class B(A, object): pass
... 
>>> 
>>> class C(B): pass
... 
>>> class D(B,A): pass
... 
>>> 

关于python - Python 中的动态子类化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8944320/

相关文章:

python - 任务 Celery 中的 RuntimeError : Never call result. get()

python - datetime 如何理解第 53 周?

c - 通过动态分配的结构变量获取用户输入的字符串

java - 使用 Groovy 动态更改 Java 应用程序的行为

python - 我正在寻找一个函数,它有助于在 python 中的特定特殊字符之后从文件中读取字符串

python - PySide:小部件插槽的多个装饰器

Swift 字典键类型

java - Java 中的变量继承

Java 反射 : invoking inherited methods from child class

php - 在运行时在 php 中添加文本字段