Просто добавьте атрибут __class__ = cls
:
def clone(cls):
namespace = dict(vars(cls), __class__=cls)
return type(cls)("Clone" + cls.__name__, cls.__bases__, namespace)
CloneA()
вызовы CloneA.__call__(CloneA)
разрешены в type.__call__(CloneA)
, который вызывает CloneA.__new__(CloneA)
разрешено в type.__new__(CloneA)
для создания экземпляра self
из CloneA
, за которым следует CloneA.__init__(self)
, который вызывает A.__init__(self)
. Наконец, последний вызывает super()
(сокращение от super(__class__, self)
), который проверяет, что self
является экземпляром или подклассом __class__
, который принадлежит A
, то есть self.__class__
или type(self)
является подклассом A
. type(self)
всегда возвращает CloneA
, а self.__class__
может отличаться, как упоминал Гвидо в PEP 3119 :
Кроме того, isinstance(x, B)
эквивалентно issubclass(x.__class__, B) or issubclass(type(x), B)
. (Возможно, type(x)
и x.__class__
не являются одним и тем же объектом, например, когда x
является прокси-объектом.)