search
HomeBackend DevelopmentPython TutorialHow to define multiple constructor method overloading and generic methods in Python classes

    What is a "generic method"?

    A method composed of multiple methods that implement the same operation for different types.

    For example

    Now there is a requirement that requires you to create a custom date class (CustomDate) in the following ways:

    • Time stamp

    • Year, month, day (a tuple containing three integers)

    • Characters in ISO format String

    • Datetime Class

    General implementation

    from datetime import date, datetime
    class CustomDate:
        def __init__(self, arg):
            if isinstance(arg, (int, float)):
                self.__date = date.fromtimestamp(arg)
            elif isinstance(arg, tuple) and len(arg) == 3 and all(map(lambda x: isinstance(x, int), arg):
                self.__date = date(*arg)
            elif isinstance(arg, str):
                self.__date = date.fromisoformat(arg)
            elif isinstance(arg, datetime):
                self.__date = datetime.date()
            else:
                raise TypeError("could not create instance from " + type(arg).__name__)
        @property
        def date():
            return self.__date

    Note: Incoming will not be discussed here. Whether the date/time stamp is legal or not, we only make a rough judgment on the type.

    Is there a better way?

    We can split different building methods into multiple methods and use the singledispatchmethod decorator in functools to decide which one to call based on the type of parameters passed in method.

    from datetime import date, datetime
    from functools import singledispatchmethod
    class CustomDate:
        @singledispatchmethod
        def __init__(self, arg):
            raise TypeError("could not create instance from " + type(arg).__name__)
        @__init__.register(int)
        @__init__.register(float)
        def __from_timestamp(self, arg):
            self.__date = date.fromtimestamp(arg)
        @__init__.register(tuple)
        def __from_tuple(self, arg):
            if len(arg) == 3 and all(map(lambda x: isinstance(x, int), arg)):
                self.__date = date(*arg)
            else:
                raise ValueError("could not create instance from a malformed tuple")
        @__init__.register(str)
        def __from_isoformat(self, arg):
            self.__date = date.fromisoformat(arg)
        @__init__.register(datetime)
        def __from_datetime(self, arg):
            self.__date = arg.date()
        @property
        def date(self):
            return self.__date

    In this way, we can separate the initialization of each parameter type into separate methods.

    Disadvantages

    #1 Single dispatch

    Which method implementation should be used during the call is determined by the dispatch algorithm. If the algorithm decides which method implementation to use based only on the type of a single parameter, it is called single dispatch.

    singledispatchmethod It is single dispatch. That is, only the first parameter will be considered. This is far from enough in actual business.

    #2 does not support typing

    However, as above, we still need to use if/else to determine the type of elements in the tuple. That is, we cannot use typing.Tuple[int, int, int].

    As a compromise, perhaps we can define a ThreeIntTuple class to limit it and isolate these judgments from the CustomDate class.

    I only provide an idea here for your reference, I will not implement it (because we have a better way xD).

    Alternative: multimethod library

    This library is not one of the standard libraries and needs to be installed through pip:

    pip install multimethod

    Advantages

    multimethod It uses a multi-dispatch algorithm, which can better meet more complex scenarios. In addition, the library also has good support for types in typing.

    Better way to practice

    Back to the above question, we can improve it like this:

    • Use multimethod method To replace singledispatchmethod;

    • Use Tuple[int, int, int] to replace tuple, no longer needed Manually verify the length and element type of the tuple;

    from datetime import date, datetime
    from typing import Tuple, Union
    from multimethod import multimethod
    class CustomDate:
        @multimethod
        def __init__(self, arg):
            raise TypeError("could not create instance from " + type(arg).__name__)
        @__init__.register
        def __from_timestamp(self, arg: Union[int, float]):
            self.__date = date.fromtimestamp(arg)
        @__init__.register
        def __from_tuple(self, arg: Tuple[int, int, int]):
            self.__date = date(*arg)
        @__init__.register
        def __from_isoformat(self, arg: str):
            self.__date = date.fromisoformat(arg)
        @__init__.register
        def __from_datetime(self, arg: datetime):
            self.__date = arg.date()
        @property
        def date(self):
            return self.__date

    The ultimate practical way (real method overloading)

    Before doing this, ask first A simple question for everyone (this is closely related to our next content):

    class A:
        def a(self):
            print(1)
        def a(self):
            print(2)
    A().a()

    What will the above code output? Or will it throw an error?

    Output 2.

    In Python, if methods with duplicate names are defined, the last method will overwrite the previous method.

    But you may not know that we can change this behavior through metaclass:

    class MetaA(type):
        class __prepare__(dict):
            def __init__(*args):
                pass
            def __setitem__(self, key, value):
                if self.get('a'):  # Line 7
                    super().__setitem__('b', value)  # Line 8
                else:	
                    super().__setitem__(key, value)
    class A(metaclass=MetaA):
        def a(self):
            print(1)
        def a(self):
            print(2)
    A().a()  # => 1
    A().b()  # => 2  # Line 22

    In lines 7 and 8, we will a## with the same name # The method is renamed b and is successfully called on line 22. The maintainers of

    multimethod have made good use of this and processed methods with duplicate names to achieve a "special effect".

    Back to the topic, we can make the following improvements:

    • Set

      multimethod.multidata to the CustomDate class Metaclass;

    • Name all methods

      __init__.

    • from datetime import date, datetime
      from typing import Tuple, Union
      from multimethod import multimeta
      class CustomDate(metaclass=multimeta):
          def __init__(self, arg: Union[int, float]):
              self.__date = date.fromtimestamp(arg)
          def __init__(self, arg: Tuple[int, int, int]):
              self.__date = date(*arg)
          def __init__(self, arg: str):
              self.__date = date.fromisoformat(arg)
          def __init__(self, arg: datetime):
              self.__date = arg.date()
          def __init__(self, arg):
              raise TypeError("could not create instance from " + type(arg).__name__)
          @property
          def date(self):
              return self.__date
    In terms of effect, this is exactly the same as method overloading in static languages!

    The above is the detailed content of How to define multiple constructor method overloading and generic methods in Python classes. For more information, please follow other related articles on the PHP Chinese website!

    Statement
    This article is reproduced at:亿速云. If there is any infringement, please contact admin@php.cn delete
    Merging Lists in Python: Choosing the Right MethodMerging Lists in Python: Choosing the Right MethodMay 14, 2025 am 12:11 AM

    TomergelistsinPython,youcanusethe operator,extendmethod,listcomprehension,oritertools.chain,eachwithspecificadvantages:1)The operatorissimplebutlessefficientforlargelists;2)extendismemory-efficientbutmodifiestheoriginallist;3)listcomprehensionoffersf

    How to concatenate two lists in python 3?How to concatenate two lists in python 3?May 14, 2025 am 12:09 AM

    In Python 3, two lists can be connected through a variety of methods: 1) Use operator, which is suitable for small lists, but is inefficient for large lists; 2) Use extend method, which is suitable for large lists, with high memory efficiency, but will modify the original list; 3) Use * operator, which is suitable for merging multiple lists, without modifying the original list; 4) Use itertools.chain, which is suitable for large data sets, with high memory efficiency.

    Python concatenate list stringsPython concatenate list stringsMay 14, 2025 am 12:08 AM

    Using the join() method is the most efficient way to connect strings from lists in Python. 1) Use the join() method to be efficient and easy to read. 2) The cycle uses operators inefficiently for large lists. 3) The combination of list comprehension and join() is suitable for scenarios that require conversion. 4) The reduce() method is suitable for other types of reductions, but is inefficient for string concatenation. The complete sentence ends.

    Python execution, what is that?Python execution, what is that?May 14, 2025 am 12:06 AM

    PythonexecutionistheprocessoftransformingPythoncodeintoexecutableinstructions.1)Theinterpreterreadsthecode,convertingitintobytecode,whichthePythonVirtualMachine(PVM)executes.2)TheGlobalInterpreterLock(GIL)managesthreadexecution,potentiallylimitingmul

    Python: what are the key featuresPython: what are the key featuresMay 14, 2025 am 12:02 AM

    Key features of Python include: 1. The syntax is concise and easy to understand, suitable for beginners; 2. Dynamic type system, improving development speed; 3. Rich standard library, supporting multiple tasks; 4. Strong community and ecosystem, providing extensive support; 5. Interpretation, suitable for scripting and rapid prototyping; 6. Multi-paradigm support, suitable for various programming styles.

    Python: compiler or Interpreter?Python: compiler or Interpreter?May 13, 2025 am 12:10 AM

    Python is an interpreted language, but it also includes the compilation process. 1) Python code is first compiled into bytecode. 2) Bytecode is interpreted and executed by Python virtual machine. 3) This hybrid mechanism makes Python both flexible and efficient, but not as fast as a fully compiled language.

    Python For Loop vs While Loop: When to Use Which?Python For Loop vs While Loop: When to Use Which?May 13, 2025 am 12:07 AM

    Useaforloopwheniteratingoverasequenceorforaspecificnumberoftimes;useawhileloopwhencontinuinguntilaconditionismet.Forloopsareidealforknownsequences,whilewhileloopssuitsituationswithundeterminediterations.

    Python loops: The most common errorsPython loops: The most common errorsMay 13, 2025 am 12:07 AM

    Pythonloopscanleadtoerrorslikeinfiniteloops,modifyinglistsduringiteration,off-by-oneerrors,zero-indexingissues,andnestedloopinefficiencies.Toavoidthese:1)Use'i

    See all articles

    Hot AI Tools

    Undresser.AI Undress

    Undresser.AI Undress

    AI-powered app for creating realistic nude photos

    AI Clothes Remover

    AI Clothes Remover

    Online AI tool for removing clothes from photos.

    Undress AI Tool

    Undress AI Tool

    Undress images for free

    Clothoff.io

    Clothoff.io

    AI clothes remover

    Video Face Swap

    Video Face Swap

    Swap faces in any video effortlessly with our completely free AI face swap tool!

    Hot Article

    Hot Tools

    Dreamweaver Mac version

    Dreamweaver Mac version

    Visual web development tools

    ZendStudio 13.5.1 Mac

    ZendStudio 13.5.1 Mac

    Powerful PHP integrated development environment

    Notepad++7.3.1

    Notepad++7.3.1

    Easy-to-use and free code editor

    WebStorm Mac version

    WebStorm Mac version

    Useful JavaScript development tools

    SAP NetWeaver Server Adapter for Eclipse

    SAP NetWeaver Server Adapter for Eclipse

    Integrate Eclipse with SAP NetWeaver application server.