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

如何通过继承实现Click命令代码去重?以lidtk分类器为例

实现Click命令的继承与代码去重

当然可以!你遇到的这种重复Click命令结构的场景,完全可以通过抽象通用逻辑+继承/工厂模式来实现代码复用,彻底消除冗余。下面给你两种适配你场景的实用方案:

方案一:创建带通用CLI命令的基类

既然所有分类器都继承自lidtk.LIDClassifier,我们可以再封装一个带Click命令的中间基类,把重复的命令逻辑全部放在这里,让具体分类器类直接继承它即可。

步骤1:定义通用CLI基类

在lidtk库中新增一个base_cli.py文件,写入以下代码:

import click
from lidtk import LIDClassifier

class BaseCLIClassifier(LIDClassifier):
    @classmethod
    def create_cli(cls, module_name):
        """生成当前分类器的Click命令组"""
        @click.group(help=f"Use the {module_name} language classifier.")
        def cli():
            pass

        # 绑定通用命令到分类器实例
        classifier = cls()

        @cli.command()
        def get_languages():
            """获取当前分类器支持的语言列表"""
            languages = classifier.get_supported_languages()
            click.echo("\n".join(languages))

        @cli.command()
        @click.argument("text")
        def predict(text):
            """预测输入文本的语言"""
            result = classifier.predict_language(text)
            click.echo(result)

        @cli.command()
        def print_languages():
            """格式化打印支持的语言列表"""
            languages = classifier.get_supported_languages()
            click.echo(f"Supported languages ({len(languages)}):")
            for lang in sorted(languages):
                click.echo(f"- {lang}")

        @cli.command()
        def wili():
            """在WILI数据集上运行评估"""
            classifier.evaluate_wili()
            click.echo("WILI evaluation completed.")

        @cli.command()
        @click.argument("k", type=int)
        def wili_k(k):
            """在WILI数据集上运行Top-K评估"""
            classifier.evaluate_wili_top_k(k)
            click.echo(f"WILI top-{k} evaluation completed.")

        @cli.command()
        def wili_unk():
            """在WILI数据集上运行未知语言评估"""
            classifier.evaluate_wili_unknown()
            click.echo("WILI unknown language evaluation completed.")

        return cli

步骤2:改造具体分类器模块

以cld2_mod.py为例,现在只需要实现分类器的核心逻辑,调用基类的方法生成CLI即可:

from lidtk.base_cli import BaseCLIClassifier
import cld2

class CLD2Classifier(BaseCLIClassifier):
    def get_supported_languages(self):
        # 实现CLD2特有的语言列表逻辑
        return ["en", "fr", "de", "es", ...]

    def predict_language(self, text):
        # 实现CLD2特有的预测逻辑
        return cld2.detect(text)[0]

    def evaluate_wili(self):
        # 实现CLD2特有的WILI评估逻辑
        pass

    # 其他评估方法同理实现...

# 生成当前模块的CLI命令组
cli = CLD2Classifier.create_cli("cld2_mod")

其他三个模块(langdetect_mod.py、langid_mod.py、text_cat.py)只需要替换类名和核心逻辑,完全复用基类的CLI命令结构。

方案二:使用工厂函数生成CLI

如果不想新增基类,也可以用工厂函数来封装通用的CLI命令生成逻辑,这种方式更轻量化:

步骤1:定义CLI工厂函数

在lidtk/utils.py中添加:

import click

def create_lid_cli(classifier_class, module_name):
    """为LID分类器生成通用Click命令组"""
    @click.group(help=f"Use the {module_name} language classifier.")
    def cli():
        pass

    classifier = classifier_class()

    # 以下命令逻辑和方案一完全一致,省略重复代码
    @cli.command()
    def get_languages():
        languages = classifier.get_supported_languages()
        click.echo("\n".join(languages))

    @cli.command()
    @click.argument("text")
    def predict(text):
        result = classifier.predict_language(text)
        click.echo(result)

    # 其余命令(print_languages、wili等)同上...

    return cli

步骤2:改造具体模块

还是以cld2_mod.py为例:

from lidtk import LIDClassifier
from lidtk.utils import create_lid_cli
import cld2

class CLD2Classifier(LIDClassifier):
    # 核心逻辑实现同上...

# 调用工厂函数生成CLI
cli = create_lid_cli(CLD2Classifier, "cld2_mod")

扩展与维护

如果未来某个分类器需要添加特定命令,只需要在生成的cli对象上额外添加即可,不会影响其他模块:

# 在cld2_mod.py中添加CLD2专属命令
@cli.command()
def cld2_debug():
    """CLD2专属调试命令"""
    click.echo("Running CLD2 debug mode...")

如果需要修改通用命令的逻辑(比如调整predict命令的参数),只需要修改基类或工厂函数中的代码,所有模块都会自动同步更新,彻底解决冗余问题。

内容的提问来源于stack exchange,提问作者Martin Thoma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:09:15