You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python无单一父类场景的类型提示:Sklearn缩放器标注咨询

问题解答

1. 恰当的类型提示方式

有两种更优雅的方案,比直接写Union或硬编码具体类更合适:

  • 基于公共父类组合:既然所有目标缩放器都继承自OneToOneFeatureMixin、TransformerMixin、BaseEstimator,可以直接用这三个类的组合作为类型提示(Python 3.10+支持|操作符表示类型并集):

    from sklearn.base import OneToOneFeatureMixin, TransformerMixin, BaseEstimator
    from abc import ABC
    import pandas as pd
    
    class FeatureEngineering(ABC):
        def __init__(self, dataframe: pd.DataFrame, scaler: OneToOneFeatureMixin | TransformerMixin | BaseEstimator | None = None):
            self.dataframe = dataframe
            self.scaler = scaler
    

    这种方式直接利用现有继承关系,静态检查工具能准确识别合规的缩放器类型。

  • 基于协议(Protocol):定义一个仅关注核心行为的协议,只要类实现了缩放器必备的方法,就会被视为符合该类型,这种方式更灵活,不局限于sklearn的继承体系:

    from typing import Protocol
    import pandas as pd
    from abc import ABC
    
    class ScalerProtocol(Protocol):
        def fit(self, X: pd.DataFrame, y=None) -> "ScalerProtocol":
            ...
        def transform(self, X: pd.DataFrame) -> pd.DataFrame:
            ...
        def fit_transform(self, X: pd.DataFrame, y=None) -> pd.DataFrame:
            ...
    
    class FeatureEngineering(ABC):
        def __init__(self, dataframe: pd.DataFrame, scaler: ScalerProtocol | None = None):
            self.dataframe = dataframe
            self.scaler = scaler
    

    自定义缩放器只要实现上述方法,就能被正确识别为合规类型。

2. Python允许创建特定类型,实现方式如下

可以通过三种方式为该场景创建专属类型:

  • 使用TypeAlias定义类型别名:轻量化地给现有类型组合起一个语义清晰的别名,静态检查时等价于原类型:

    from typing import TypeAlias
    from sklearn.base import OneToOneFeatureMixin, TransformerMixin, BaseEstimator
    
    GeneralScaler: TypeAlias = OneToOneFeatureMixin | TransformerMixin | BaseEstimator
    
    # 用法示例
    class FeatureEngineering(ABC):
        def __init__(self, dataframe: pd.DataFrame, scaler: GeneralScaler | None = None):
            self.dataframe = dataframe
            self.scaler = scaler
    
  • 使用NewType创建语义类型:给类型赋予专属名称,仅用于静态类型检查,运行时不会做额外限制:

    from typing import NewType
    from sklearn.base import OneToOneFeatureMixin, TransformerMixin, BaseEstimator
    
    GeneralScaler = NewType("GeneralScaler", OneToOneFeatureMixin | TransformerMixin | BaseEstimator)
    
    # 用法示例
    class FeatureEngineering(ABC):
        def __init__(self, dataframe: pd.DataFrame, scaler: GeneralScaler | None = None):
            self.dataframe = dataframe
            self.scaler = scaler
    
  • 使用TypeVar绑定约束类型:创建一个受约束的类型变量,限定只能是同时继承指定父类的类型,检查更严谨:

    from typing import TypeVar
    from sklearn.base import OneToOneFeatureMixin, TransformerMixin, BaseEstimator
    
    ScalerType = TypeVar("ScalerType", bound=OneToOneFeatureMixin & TransformerMixin & BaseEstimator)
    
    # 用法示例
    class FeatureEngineering(ABC):
        def __init__(self, dataframe: pd.DataFrame, scaler: ScalerType | None = None):
            self.dataframe = dataframe
            self.scaler = scaler
    

内容的提问来源于stack exchange,提问作者An old man in the sea.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 02:06:12