元编程 - 如何在使用 __class__ 时从模板生成 class?

Meta-programming - How to generate class from template when __class__ is used?

我创建了这样的 class 来解决签名问题 feature_names:

import copy
from sklearn.feature_selection import VarianceTreshold


class VarianceThresholdN(VarianceThreshold):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.feature_names = None

    #hack from     
    def get_params(self, deep=True): 
        params = super().get_params(deep)
        cp = copy.copy(self)
        cp.__class__ = VarianceThreshold
        params.update(cp.__class__.get_params(cp, deep))
        return params

    def fit(self, X, y=None):
        self.feature_names = list(X.columns)
        return super().fit(X, y)

不幸的是,我需要创建很多这样的 classes,所以需要大量复制粘贴和替换两件事: class VarianceThresholdN(VarianceThreshold):class DifferentClassN(DifferentClass):cp.__class__ = VarianceThresholdcp.__class__ = DifferentClass

所以有一个清晰的模板,但是由于cp.__class__ = ...我不能使用mix-ins。

可能这段代码可以用 jinja 模板生成,但是有什么方法可以避免它,使用元编程中的一些 pythonic 技巧吗?

我真的不明白那应该做什么,据我所知,你几乎只是调用了 super() 两次,而第二个版本明确地这样做了。

Probably this code could be generated with jinja templates, but is there any way to avoid it, with some pythonic trick from meta-programming?

如果您的模式是您总是希望为其父级 "swap" self.__class__,您可以使用 __bases__mro()[1]:[=19 访问它=]

  • cls.__bases__cls 的所有 super类 的元组,它正是你放在括号中的内容(不包括 kwargs)
  • cls.mro() 是 "method resolution order",它适用于这种特定(完全线性)的情况:它是处理属性或方法时要经过的所有 类 的序列调用,从 cls(包括)开始到 object 结束(这是所有 Python 类 的原始祖先)。