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.
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.
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.
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!