Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Fungsi lebihan dalam Python

Fungsi lebihan dalam Python

DDD
DDDasal
2024-09-24 06:24:45499semak imbas

Overloading functions in Python

Lebihan beban fungsi merujuk kepada keupayaan untuk mentakrifkan berbilang fungsi dengan nama yang sama tetapi tandatangan berbeza, bermakna ia mempunyai nombor atau jenis parameter yang berbeza. Versi fungsi yang betul dipilih secara automatik oleh pengkompil atau penterjemah, bergantung pada bilangan dan jenis hujah yang diluluskan semasa panggilan fungsi.

Bahasa seperti Java dan C++ menyokong ini sebagai ciri secara asli.

Walaupun python tidak menyokong pemuatan lebihan fungsi secara asli kerana ia adalah bahasa yang ditaip secara dinamik, adalah mungkin untuk melaksanakan perkara yang sama menggunakan pelbagai modul dan utiliti.

Ini adalah pelaksanaan saya tentang lebihan beban.

Perlaksanaan

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

Kelas OverloadNamespace ialah boleh panggil yang bertindak sebagai perantara antara nama fungsi dan tandatangan panggilan. Argumen dihantar ke dalam kaedah __call__ dunder yang sepadan dengan jenis data yang disediakan dengan tuple jenis yang disimpan dalam kamus lebihan. Tandatangan yang dipadankan dikembalikan dan dipanggil dengan args/kwargs yang disediakan. Jika tiada tandatangan yang sepadan ditemui, fungsi sandaran dipanggil.

Menggunakan kelas OverloadNamespace

Kelas ini tidak dimaksudkan untuk digunakan secara manual, ia digunakan oleh penghias yang mengubah suai fungsi dan mengembalikan contoh kelas OverloadNamespace menggunakan nama yang sama seperti nama fungsi yang disediakan.

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

Penghias terlebih beban menyemak jenis argumen menggunakan nilai penghias atau petunjuk taip dan mengembalikan kelas ruang nama.

Contoh penggunaan

# 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

Ini hanyalah idea asas dan berfungsi untuk jenis tetap bukan kesatuan.

Fallback

Fungsi sandaran digunakan sebagai fungsi yang akan dipanggil apabila tiada corak hujah sepadan dengan corak panggilan.

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

Atas ialah kandungan terperinci Fungsi lebihan dalam Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn