如何在Python中使用方法重载?

时间:2021-06-11 00:07:24

I am trying to implement method overloading in Python:

我正在尝试在Python中实现方法重载:

class A:
    def *(self):    
        print 'first method'
    def *(self, i):
        print 'second method', i

ob=A()
ob.*(2)

but the output is second method 2; similarly:

但是输出是第二个方法2;类似的:

class A:
    def *(self):    
        print 'first method'
    def *(self, i):
        print 'second method', i

ob=A()
ob.*()

gives

给了

Traceback (most recent call last):
  File "my.py", line 9, in <module>
    ob.*()
TypeError: *() takes exactly 2 arguments (1 given)

How do I make this work?

我要怎么做呢?

12 个解决方案

#1


120  

It's method overloading not method overriding. And in Python, you do it all in one function:

它是方法重载而不是方法重写。在Python中,你可以用一个函数来完成:

class A:

    def *(self, i='some_default_value'):    
        print 'only method'

ob=A()
ob.*(2)
ob.*()

You can't have two methods with the same name in Python -- and you don't need to.

在Python中,不能有两个名称相同的方法——而且不需要这样做。

See the Default Argument Values section of the Python tutorial. See "Least Astonishment" and the Mutable Default Argument for a common mistake to avoid.

请参阅Python教程的默认参数值部分。请参阅“最小惊讶”和可变默认参数,以避免常见错误。

Edit: See PEP 443 for information about the new single dispatch generic functions in Python 3.4.

编辑:有关Python 3.4中新的单分派通用函数的信息,请参见PEP 443。

#2


39  

In Python, you don't do things that way. When people do that in languages like Java, they generally want a default value (if they don't, they generally want a method with a different name). So, in Python, you can have default values.

在Python中,你不会那样做。当人们在Java等语言中这样做时,他们通常需要一个默认值(如果他们不需要,他们通常需要一个名称不同的方法)。在Python中,可以有默认值。

class A(object):  # Remember the ``object`` bit when working in Python 2.x

    def *(self, i=None):
        if i is None:
            print 'first form'
        else:
            print 'second form'

As you can see, you can use this to trigger separate behaviour rather than merely having a default value.

正如您所看到的,您可以使用它来触发单独的行为,而不仅仅是拥有一个默认值。

>>> ob = A()
>>> ob.*()
first form
>>> ob.*(2)
second form

#3


26  

You can't, never need to and don't really want to.

你不可能,永远不需要,也不想。

In Python, everything is an object. Classes are things, so they are objects. So are methods.

在Python中,一切都是对象。类是事物,所以它们是对象。方法也是如此。

There is an object called A which is a class. It has an attribute called *. It can only have one such attribute.

有一个对象叫A,它是一个类。它有一个名为*的属性。它只能有一个这样的属性。

When you write def *(...): ..., what happens is that you create an object which is the method, and assign it to the * attribute of A. If you write two definitions, the second one replaces the first, the same way that assignment always behaves.

当你写def *(…):…,所发生的是,您创建了一个对象,该对象是方法,并将其分配给a的*属性。

You furthermore do not want to write code that does the wilder of the sorts of things that overloading is sometimes used for. That's not how the language works.

此外,您也不希望编写代码,以实现有时用于重载的那种疯狂的事情。这不是语言的工作方式。

Instead of trying to define a separate function for each type of thing you could be given (which makes little sense since you don't specify types for function parameters anyway), stop worrying about what things are and start thinking about what they can do.

不要试图为可能给出的每一种类型定义一个单独的函数(这没有什么意义,因为无论如何你都没有为函数参数指定类型),停止担心事情是什么,开始考虑它们可以做什么。

You not only can't write a separate one to handle a tuple vs. a list, but also don't want or need to.

您不仅不能编写单独的一个来处理元组和列表,而且也不希望或不需要这样做。

All you do is take advantage of the fact that they are both, for example, iterable (i.e. you can write for element in container:). (The fact that they aren't directly related by inheritance is irrelevant.)

您所要做的就是利用它们都是可迭代的这一事实(例如,您可以在container:中为元素编写代码)。(事实上,它们与继承没有直接关系,这是无关的。)

#4


16  

You can also use pythonlangutil:

你也可以使用pythonlangutil:

from pythonlangutil.overload import Overload, signature

class A:
    @Overload
    @signature()
    def *(self):    
        print 'first method'

    @*.overload
    @signature("int")
    def *(self, i):
        print 'second method', i

#5


13  

I write my answer in Python 3.2.1.

我用Python 3.2.1编写答案。

def overload(*functions):
    return lambda *args, **kwargs: functions[len(args)](*args, **kwargs)

How it works:

它是如何工作的:

  1. overload takes any amount of callables and stores them in tuple functions, then returns lambda.
  2. 重载接受任意数量的可调用值,并将它们存储在tuple函数中,然后返回lambda。
  3. The lambda takes any amount of arguments, then returns result of calling function stored in functions[number_of_unnamed_args_passed] called with arguments passed to the lambda.
  4. lambda接受任何数量的参数,然后返回调用存储在函数[number_of_unnamed_args_pass]中的函数的结果,这些函数的参数传递给lambda。

Usage:

用法:

class A:
    *=overload(                    \
        None, \ 
        #there is always a self argument, so this should never get called
        lambda self: print('First method'),      \
        lambda self, i: print('Second method', i) \
    )

#6


12  

I think the word you're looking for is "overloading". There is no method overloading in python. You can however use default arguments, as follows.

我认为你要找的词是“超负荷”。在python中没有方法重载。但是,您可以使用默认参数,如下所示。

def *(self, i=None):
    if i != None:     
        print 'second method', i
    else:
        print 'first method'

When you pass it an argument it will follow the logic of the first condition and execute the first print statement. When you pass it no arguments, it will go into the else condition and execute the second print statement.

当您传递一个参数时,它将遵循第一个条件的逻辑并执行第一个print语句。当不传递参数时,它将进入else条件并执行第二个print语句。

#7


12  

I write my answer in Python 2.7:

我用Python编写答案2.7:

In Python, method overloading is not possible; if you really want access the same function with different features, I suggest you to go for method overriding.

在Python中,方法重载是不可能的;如果您真的希望访问具有不同功能的相同功能,我建议您选择方法重写。

class Base(): # Base class
    '''def add(self,a,b):
        s=a+b
        print s'''

    def add(self,a,b,c):
        self.a=a
        self.b=b
        self.c=c

        sum =a+b+c
        print sum

class Derived(Base): # Derived class
    def add(self,a,b): # overriding method
        sum=a+b
        print sum



add_fun_1=Base() #instance creation for Base class
add_fun_2=Derived()#instance creation for Derived class

add_fun_1.add(4,2,5) # function with 3 arguments
add_fun_2.add(4,2)   # function with 2 arguments

#8


8  

In Python, overloading is not an applied concept. However, if you are trying to create a case where, for instance, you want one initializer to be performed if passed an argument of type foo and another initializer for an argument of type bar then, since everything in Python is handled as object, you can check the name of the passed object's class type and write conditional handling based on that.

在Python中,重载不是一个应用的概念。然而,如果你想创建一个情况,例如,你想要一个执行初始化程序,如果程序传递一个参数类型的foo和另一个初始化参数类型的酒吧,因为一切在Python中处理对象,您可以检查传递的对象的类的名称类型和写条件处理的基础上。

class A:
   def __init__(self, arg)
      # Get the Argument's class type as a String
      argClass = arg.__class__.__name__

      if argClass == 'foo':
         print 'Arg is of type "foo"'
         ...
      elif argClass == 'bar':
         print 'Arg is of type "bar"'
         ...
      else
         print 'Arg is of a different type'
         ...

This concept can be applied to multiple different scenarios through different methods as needed.

这个概念可以根据需要通过不同的方法应用于多个不同的场景。

#9


7  

In Python, you'd do this with a default argument.

在Python中,您需要使用默认参数。

class A:

    def *(self, i=None):    
        if i == None:
            print 'first method'
        else:
            print 'second method',i

#10


5  

Just came across this https://github.com/bintoro/overloading.py for anybody who may be interested.

刚刚遇到这个https://github.com/bintoro/overload.py,任何人都可能感兴趣。

From the linked repository's readme:

来自链接库的自述:

overloading is a module that provides function dispatching based on the types and number of runtime arguments.

重载是一个模块,它根据运行时参数的类型和数量提供函数分派。

When an overloaded function is invoked, the dispatcher compares the supplied arguments to available function signatures and calls the implementation that provides the most accurate match.

当调用重载的函数时,dispatcher将提供的参数与可用的函数签名进行比较,并调用提供最精确匹配的实现。

Features

特性

Function validation upon registration and detailed resolution rules guarantee a unique, well-defined outcome at runtime. Implements function resolution caching for great performance. Supports optional parameters (default values) in function signatures. Evaluates both positional and keyword arguments when resolving the best match. Supports fallback functions and execution of shared code. Supports argument polymorphism. Supports classes and inheritance, including classmethods and staticmethods.

注册和详细的解决规则的功能验证在运行时保证了一个独特的、定义良好的结果。实现函数解析缓存以获得更好的性能。在函数签名中支持可选参数(默认值)。在解决最佳匹配时,评估位置和关键字参数。支持回退函数和共享代码的执行。支持参数多态性。支持类和继承,包括类方法和静态方法。

#11


0  

Python does not support method overloading like Java or C++. We may overload the methods but can only use the latest defined method.

Python不支持Java或c++等方法重载。我们可以重载方法,但只能使用最新定义的方法。

# First sum method.
# Takes two argument and print their sum
def sum(a, b):
    s = a + b
    print(s)

# Second sum method
# Takes three argument and print their sum
def sum(a, b, c):
    s = a + b + c
    print(s)

# Uncommenting the below line shows an error    
# sum(4, 5)

# This line will call the second product method
sum(4, 5, 5)

We need to provide optional arguments or *args in order to provide different number of args on calling.

我们需要提供可选参数或*args,以便在调用时提供不同数量的args。

Courtesy from https://www.geeksforgeeks.org/python-method-overloading/

从https://www.geeksforgeeks.org/python-method-overloading/礼貌

#12


-1  

In MathMethod.py file

在MathMethod。py文件

from multipledispatch import dispatch
@dispatch(int,int)
def Add(a,b):
   return a+b 
@dispatch(int,int,int)  
def Add(a,b,c):
   return a+b+c 
@dispatch(int,int,int,int)    
def Add(a,b,c,d):
   return a+b+c+d

In Main.py file

在主。py文件

import MathMethod as MM 
print(MM.Add(200,1000,1000,200))

We can overload method by using multipledispatch

我们可以通过多路调度来重载方法

#1


120  

It's method overloading not method overriding. And in Python, you do it all in one function:

它是方法重载而不是方法重写。在Python中,你可以用一个函数来完成:

class A:

    def *(self, i='some_default_value'):    
        print 'only method'

ob=A()
ob.*(2)
ob.*()

You can't have two methods with the same name in Python -- and you don't need to.

在Python中,不能有两个名称相同的方法——而且不需要这样做。

See the Default Argument Values section of the Python tutorial. See "Least Astonishment" and the Mutable Default Argument for a common mistake to avoid.

请参阅Python教程的默认参数值部分。请参阅“最小惊讶”和可变默认参数,以避免常见错误。

Edit: See PEP 443 for information about the new single dispatch generic functions in Python 3.4.

编辑:有关Python 3.4中新的单分派通用函数的信息,请参见PEP 443。

#2


39  

In Python, you don't do things that way. When people do that in languages like Java, they generally want a default value (if they don't, they generally want a method with a different name). So, in Python, you can have default values.

在Python中,你不会那样做。当人们在Java等语言中这样做时,他们通常需要一个默认值(如果他们不需要,他们通常需要一个名称不同的方法)。在Python中,可以有默认值。

class A(object):  # Remember the ``object`` bit when working in Python 2.x

    def *(self, i=None):
        if i is None:
            print 'first form'
        else:
            print 'second form'

As you can see, you can use this to trigger separate behaviour rather than merely having a default value.

正如您所看到的,您可以使用它来触发单独的行为,而不仅仅是拥有一个默认值。

>>> ob = A()
>>> ob.*()
first form
>>> ob.*(2)
second form

#3


26  

You can't, never need to and don't really want to.

你不可能,永远不需要,也不想。

In Python, everything is an object. Classes are things, so they are objects. So are methods.

在Python中,一切都是对象。类是事物,所以它们是对象。方法也是如此。

There is an object called A which is a class. It has an attribute called *. It can only have one such attribute.

有一个对象叫A,它是一个类。它有一个名为*的属性。它只能有一个这样的属性。

When you write def *(...): ..., what happens is that you create an object which is the method, and assign it to the * attribute of A. If you write two definitions, the second one replaces the first, the same way that assignment always behaves.

当你写def *(…):…,所发生的是,您创建了一个对象,该对象是方法,并将其分配给a的*属性。

You furthermore do not want to write code that does the wilder of the sorts of things that overloading is sometimes used for. That's not how the language works.

此外,您也不希望编写代码,以实现有时用于重载的那种疯狂的事情。这不是语言的工作方式。

Instead of trying to define a separate function for each type of thing you could be given (which makes little sense since you don't specify types for function parameters anyway), stop worrying about what things are and start thinking about what they can do.

不要试图为可能给出的每一种类型定义一个单独的函数(这没有什么意义,因为无论如何你都没有为函数参数指定类型),停止担心事情是什么,开始考虑它们可以做什么。

You not only can't write a separate one to handle a tuple vs. a list, but also don't want or need to.

您不仅不能编写单独的一个来处理元组和列表,而且也不希望或不需要这样做。

All you do is take advantage of the fact that they are both, for example, iterable (i.e. you can write for element in container:). (The fact that they aren't directly related by inheritance is irrelevant.)

您所要做的就是利用它们都是可迭代的这一事实(例如,您可以在container:中为元素编写代码)。(事实上,它们与继承没有直接关系,这是无关的。)

#4


16  

You can also use pythonlangutil:

你也可以使用pythonlangutil:

from pythonlangutil.overload import Overload, signature

class A:
    @Overload
    @signature()
    def *(self):    
        print 'first method'

    @*.overload
    @signature("int")
    def *(self, i):
        print 'second method', i

#5


13  

I write my answer in Python 3.2.1.

我用Python 3.2.1编写答案。

def overload(*functions):
    return lambda *args, **kwargs: functions[len(args)](*args, **kwargs)

How it works:

它是如何工作的:

  1. overload takes any amount of callables and stores them in tuple functions, then returns lambda.
  2. 重载接受任意数量的可调用值,并将它们存储在tuple函数中,然后返回lambda。
  3. The lambda takes any amount of arguments, then returns result of calling function stored in functions[number_of_unnamed_args_passed] called with arguments passed to the lambda.
  4. lambda接受任何数量的参数,然后返回调用存储在函数[number_of_unnamed_args_pass]中的函数的结果,这些函数的参数传递给lambda。

Usage:

用法:

class A:
    *=overload(                    \
        None, \ 
        #there is always a self argument, so this should never get called
        lambda self: print('First method'),      \
        lambda self, i: print('Second method', i) \
    )

#6


12  

I think the word you're looking for is "overloading". There is no method overloading in python. You can however use default arguments, as follows.

我认为你要找的词是“超负荷”。在python中没有方法重载。但是,您可以使用默认参数,如下所示。

def *(self, i=None):
    if i != None:     
        print 'second method', i
    else:
        print 'first method'

When you pass it an argument it will follow the logic of the first condition and execute the first print statement. When you pass it no arguments, it will go into the else condition and execute the second print statement.

当您传递一个参数时,它将遵循第一个条件的逻辑并执行第一个print语句。当不传递参数时,它将进入else条件并执行第二个print语句。

#7


12  

I write my answer in Python 2.7:

我用Python编写答案2.7:

In Python, method overloading is not possible; if you really want access the same function with different features, I suggest you to go for method overriding.

在Python中,方法重载是不可能的;如果您真的希望访问具有不同功能的相同功能,我建议您选择方法重写。

class Base(): # Base class
    '''def add(self,a,b):
        s=a+b
        print s'''

    def add(self,a,b,c):
        self.a=a
        self.b=b
        self.c=c

        sum =a+b+c
        print sum

class Derived(Base): # Derived class
    def add(self,a,b): # overriding method
        sum=a+b
        print sum



add_fun_1=Base() #instance creation for Base class
add_fun_2=Derived()#instance creation for Derived class

add_fun_1.add(4,2,5) # function with 3 arguments
add_fun_2.add(4,2)   # function with 2 arguments

#8


8  

In Python, overloading is not an applied concept. However, if you are trying to create a case where, for instance, you want one initializer to be performed if passed an argument of type foo and another initializer for an argument of type bar then, since everything in Python is handled as object, you can check the name of the passed object's class type and write conditional handling based on that.

在Python中,重载不是一个应用的概念。然而,如果你想创建一个情况,例如,你想要一个执行初始化程序,如果程序传递一个参数类型的foo和另一个初始化参数类型的酒吧,因为一切在Python中处理对象,您可以检查传递的对象的类的名称类型和写条件处理的基础上。

class A:
   def __init__(self, arg)
      # Get the Argument's class type as a String
      argClass = arg.__class__.__name__

      if argClass == 'foo':
         print 'Arg is of type "foo"'
         ...
      elif argClass == 'bar':
         print 'Arg is of type "bar"'
         ...
      else
         print 'Arg is of a different type'
         ...

This concept can be applied to multiple different scenarios through different methods as needed.

这个概念可以根据需要通过不同的方法应用于多个不同的场景。

#9


7  

In Python, you'd do this with a default argument.

在Python中,您需要使用默认参数。

class A:

    def *(self, i=None):    
        if i == None:
            print 'first method'
        else:
            print 'second method',i

#10


5  

Just came across this https://github.com/bintoro/overloading.py for anybody who may be interested.

刚刚遇到这个https://github.com/bintoro/overload.py,任何人都可能感兴趣。

From the linked repository's readme:

来自链接库的自述:

overloading is a module that provides function dispatching based on the types and number of runtime arguments.

重载是一个模块,它根据运行时参数的类型和数量提供函数分派。

When an overloaded function is invoked, the dispatcher compares the supplied arguments to available function signatures and calls the implementation that provides the most accurate match.

当调用重载的函数时,dispatcher将提供的参数与可用的函数签名进行比较,并调用提供最精确匹配的实现。

Features

特性

Function validation upon registration and detailed resolution rules guarantee a unique, well-defined outcome at runtime. Implements function resolution caching for great performance. Supports optional parameters (default values) in function signatures. Evaluates both positional and keyword arguments when resolving the best match. Supports fallback functions and execution of shared code. Supports argument polymorphism. Supports classes and inheritance, including classmethods and staticmethods.

注册和详细的解决规则的功能验证在运行时保证了一个独特的、定义良好的结果。实现函数解析缓存以获得更好的性能。在函数签名中支持可选参数(默认值)。在解决最佳匹配时,评估位置和关键字参数。支持回退函数和共享代码的执行。支持参数多态性。支持类和继承,包括类方法和静态方法。

#11


0  

Python does not support method overloading like Java or C++. We may overload the methods but can only use the latest defined method.

Python不支持Java或c++等方法重载。我们可以重载方法,但只能使用最新定义的方法。

# First sum method.
# Takes two argument and print their sum
def sum(a, b):
    s = a + b
    print(s)

# Second sum method
# Takes three argument and print their sum
def sum(a, b, c):
    s = a + b + c
    print(s)

# Uncommenting the below line shows an error    
# sum(4, 5)

# This line will call the second product method
sum(4, 5, 5)

We need to provide optional arguments or *args in order to provide different number of args on calling.

我们需要提供可选参数或*args,以便在调用时提供不同数量的args。

Courtesy from https://www.geeksforgeeks.org/python-method-overloading/

从https://www.geeksforgeeks.org/python-method-overloading/礼貌

#12


-1  

In MathMethod.py file

在MathMethod。py文件

from multipledispatch import dispatch
@dispatch(int,int)
def Add(a,b):
   return a+b 
@dispatch(int,int,int)  
def Add(a,b,c):
   return a+b+c 
@dispatch(int,int,int,int)    
def Add(a,b,c,d):
   return a+b+c+d

In Main.py file

在主。py文件

import MathMethod as MM 
print(MM.Add(200,1000,1000,200))

We can overload method by using multipledispatch

我们可以通过多路调度来重载方法