Python 如何从使用生成器实例化的类继承?

Python 如何从使用生成器实例化的类继承?,python,inheritance,builder,metaclass,Python,Inheritance,Builder,Metaclass,我有一个类文档,这个类实例化起来非常复杂,所以我有一个builder对象来创建它们。这两个元素都不是我的,所以我无法更改它们 现在,我想创建Document的一个子类,只是添加一些特定的方法。为了继续使用提供的生成器,我尝试了以下方法: class SpecialDocument(Document): def __new__(cls, *args): return DocumentBuilder(*args) def __init__(self, *arg

我有一个类文档,这个类实例化起来非常复杂,所以我有一个builder对象来创建它们。这两个元素都不是我的,所以我无法更改它们

现在,我想创建Document的一个子类,只是添加一些特定的方法。为了继续使用提供的生成器,我尝试了以下方法:

class SpecialDocument(Document):
     def __new__(cls, *args):
         return DocumentBuilder(*args)

     def __init__(self, *args, **kwargs):
         #My initialization
这里的问题是
\uuuuu init\uuuuuuu
方法永远不会执行,因为
\uuuu new\uuuuuuuu
方法不返回
特殊文档(它返回
文档


在我的特殊情况下,我不需要构建与构建
文档
不同的
特殊文档。有没有办法使用相同的生成器?如果没有,我如何才能做到这一点?我只想继承
文档
来添加特定的功能,也许可以用元类实现,但我从未使用过它们(可能是因为我不完全理解它),如果它能帮助解决我的问题,那么对它们有一点了解将是很好的

这里实际上不需要元类-您只需要正确地调用超类“
\uuu new\uu
方法。按照您的方式,超类的实例化根本不“知道”它是从子类调用的

因此,只需像这样编写代码:

class SpecialDocument(Document):
     def __new__(cls, *args):
         return super().__new__(cls, *args)

     def __init__(self, *args, **kwargs):
         #My initialization
现在,这是一种普通的方法——如果“构建器”函数中的代码正确地放在document的
\uuuu new\uuuu
\uuuuu init\uuuu
中,它就会起作用
由于那里的代码不这样做,并且您不能将子类作为参数传递给构建器,一个可行的解决方案可能是创建一个普通文档,并在构建后交换其类:

def special_document_init(special_document):
    ...

class SpecialDocument(Document):
    def my_special_method(self, ...):
         ...
    def overriden_method(self):
         ...
         result = super().overriden_method()
         ...

def build_special_document(*args):
    document = DocumentBuilder(*args)
    document.__class__ = SpecialDocument
    special_document_init(document)
    return document

你真的需要一个子类吗?难道你不能只使用委派来添加你想要的行为吗?
Document
DocumentBuilder
之间的关系是什么?@PhilipTzou
DocumentBuilder
是一个独立的类,如果它是在没有参数或initia的情况下构造的,它会返回一个新的
Document
对象如果它接收到一个参数,则指定它的变量(如果存在,则该参数是实际文档的路径)@Bakuriu我选择了subclass选项,因为我有多个
SpecialDocument
s,它们都有
Document
行为的共同点,但是如果您认为委派是一个更好的选项,我很乐意接受它,您可以有一个包含
Document
作为属性的公共类
MyBaseDocument
e并将大部分功能委托给文档,然后让其他专用子类继承自此子类。