ホームページ バックエンド開発 Python チュートリアル Python での関数のオーバーロード

Python での関数のオーバーロード

Sep 24, 2024 am 06:24 AM

Overloading functions in Python

関数のオーバーロードとは、名前は同じだがシグネチャが異なる複数の関数を定義する機能を指します。つまり、関数のパラメーターの数や型が異なります。関数の正しいバージョンは、関数呼び出し中に渡される引数の数と型に応じて、コンパイラーまたはインタープリターによって自動的に選択されます。

Java や C++ などの言語は、これを機能としてネイティブにサポートしています。

Python は動的に型付けされた言語であるため、関数のオーバーロードをネイティブにサポートしていませんが、さまざまなモジュールやユーティリティを使用して同じものを実装することは可能です。

これは私によるオーバーロードの実装です。

実装

from __future__ import annotations

import inspect
import typing

bin: dict[str, OverloadNamespace] = {}


class OverloadNamespace:
    overloads: dict[tuple[type, ...], typing.Callable[..., typing.Any]]
    fallback: typing.Callable[..., typing.Any]

    def __init__(self, name: str) -> None:
        self.overloads = {}
        self.fallback = self._fallback
        bin[name] = self

    def __call__(self, *args: typing.Any, **kwds: typing.Any) -> typing.Any:
        types = [type(arg) for arg in args]
        types.extend([type(kwrg) for kwrg in kwds])
        try:
            return self.overloads[tuple(types)](*args, **kwds)
        except KeyError:
            return self.fallback(*args, **kwds)

    @staticmethod
    def _fallback(*_, **__) -> None:
        raise NotImplementedError
ログイン後にコピー

OverloadNamespace クラスは、関数名と呼び出し署名の間の媒体として機能する呼び出し可能クラスです。引数は __call__ dunder メソッドに渡され、指定されたデータ型とオーバーロード ディクショナリに格納されている型タプルを照合します。一致した署名が返され、指定された引数/kwargs を使用して呼び出されます。一致する署名が見つからない場合は、フォールバック関数が呼び出されます。

OverloadNamespace クラスの使用

このクラスは手動で使用することを意図したものではなく、関数を変更し、関数の指定された名前と同じ名前を使用して OverloadNamespace クラスのインスタンスを返すデコレータによって利用されます。

def overload(*args) -> typing.Callable[..., OverloadNamespace] | OverloadNamespace:
    """Decorator used to create overloads of functions with same name. Returns a [OverloadNamespace]"""
    if len(args) == 1 and inspect.isfunction(args[0]):
        return overload_using_types(args[0])

    def inner(func: typing.Callable[..., typing.Any]) -> OverloadNamespace:
        sig = inspect.signature(func)
        assert len(args) == len(
            sig.parameters
        ), "Number of types and args in function is not same."

        namespace = (
            bin[func.__name__]
            if bin.get(func.__name__)
            else OverloadNamespace(func.__name__)
        )
        namespace.overloads[tuple(args)] = func
        return namespace

    return inner

def overload_using_types(func: typing.Callable[..., typing.Any]) -> OverloadNamespace:
    args = inspect.signature(func).parameters
    types = tuple(arg.annotation for arg in args.values())

    namespace = (
        bin[func.__name__]
        if bin.get(func.__name__)
        else OverloadNamespace(func.__name__)
    )

    namespace.overloads[types] = func
    return namespace
ログイン後にコピー

オーバーロード デコレータは、デコレータ値またはタイプヒントを使用して引数の型をチェックし、名前空間クラスを返します。

使用例

# types in decorator
@overload(int, int)
def sum(a, b):
    return a+b

# or as typehints
@overload 
def sum(a: float, b: float):
    return int(a+b)+1

sum(1,2) # 3
sum(1.23, 2.0) # 4
ログイン後にコピー

これは単なる基本的な考え方であり、非共用体固定タイプに機能します。

後退する

フォールバック関数は、呼び出しパターンに一致する引数パターンがない場合に呼び出される関数として使用されます。

def fallback(
    func: typing.Callable[..., typing.Any],
) -> OverloadNamespace:
    """Fallback function to be called if no overloads match to the provided arguments."""
    namespace = (
        bin[func.__name__]
        if bin.get(func.__name__)
        else OverloadNamespace(func.__name__)
    )
    namespace.fallback = func
    return namespace

@fallback 
def sum(*args):
    return sum(args)

sum(1,2,3,4) # 10
ログイン後にコピー

以上がPython での関数のオーバーロードの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Pythonを使用してテキストファイルのZIPF配布を見つける方法 Pythonを使用してテキストファイルのZIPF配布を見つける方法 Mar 05, 2025 am 09:58 AM

Pythonを使用してテキストファイルのZIPF配布を見つける方法

Pythonでファイルをダウンロードする方法 Pythonでファイルをダウンロードする方法 Mar 01, 2025 am 10:03 AM

Pythonでファイルをダウンロードする方法

Pythonでの画像フィルタリング Pythonでの画像フィルタリング Mar 03, 2025 am 09:44 AM

Pythonでの画像フィルタリング

HTMLを解析するために美しいスープを使用するにはどうすればよいですか? HTMLを解析するために美しいスープを使用するにはどうすればよいですか? Mar 10, 2025 pm 06:54 PM

HTMLを解析するために美しいスープを使用するにはどうすればよいですか?

Pythonを使用してPDFドキュメントの操作方法 Pythonを使用してPDFドキュメントの操作方法 Mar 02, 2025 am 09:54 AM

Pythonを使用してPDFドキュメントの操作方法

DjangoアプリケーションでRedisを使用してキャッシュする方法 DjangoアプリケーションでRedisを使用してキャッシュする方法 Mar 02, 2025 am 10:10 AM

DjangoアプリケーションでRedisを使用してキャッシュする方法

Natural Language Toolkit(NLTK)の紹介 Natural Language Toolkit(NLTK)の紹介 Mar 01, 2025 am 10:05 AM

Natural Language Toolkit(NLTK)の紹介

TensorflowまたはPytorchで深い学習を実行する方法は? TensorflowまたはPytorchで深い学習を実行する方法は? Mar 10, 2025 pm 06:52 PM

TensorflowまたはPytorchで深い学習を実行する方法は?

See all articles