如何使用方法重载在Python?如何使用方法重载在Python?(How do I use meth

2019-05-13 14:14发布

我想在Python中实现方法的重载:

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

ob=A()
ob.stackoverflow(2)

但输出是second method 2 ; 类似的:

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

ob=A()
ob.stackoverflow()

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

如何使这项工作?

Answer 1:

这方法重载不是方法覆盖 。 而在Python中,你做这一切在一个功能:

class A:

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

ob=A()
ob.stackoverflow(2)
ob.stackoverflow()

你不能有两个方法可以用Python相同的名字 - 你不需要。

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

编辑 :请参阅PEP 443大约在Python 3.4新单牒的通用功能的信息。



Answer 2:

在Python,你不这样做事情的方式。 当人们这样做,在像Java语言,他们一般需要有一个默认值(如果他们不这样做,他们普遍希望用不同的名称的方法)。 因此,在Python中, 你可以有默认值 。

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

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

正如你所看到的,你可以用它来触发不同的行为,而不是仅仅有一个默认值。

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


Answer 3:

您还可以使用pythonlangutil :

from pythonlangutil.overload import Overload, signature

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

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

编辑:随着在Python 3重载可以使用的官方支持@overload装饰。



Answer 4:

你不能,永远需要和真的不想要。

在Python中,一切都是对象。 类事情,所以他们的对象。 那么,方法。

有称为对象A这是一个类。 它具有称为属性stackoverflow 。 它只能有一个这样的属性。

当你写def stackoverflow(...): ... ,什么情况是,你创建一个对象,它是该方法,并将其分配给该stackoverflow的属性A 。 如果你写了两个定义,第二个取代第一,同样的方式,分配行为始终。

你还不想编写代码,这是否超载有时用于各种各样的事情的狂野。 这就是语言不是如何工作的。

而不是试图定义一个单独的函数的事情每种类型,你可以给予(这没有什么意义,因为你不反正指定类型的函数参数), 不用担心有什么事情 ,并开始思考自己能做些什么

你不仅不能写一个单独的一个处理一个元组与列表,但也不希望或需要

所有你要做的是采取的事实,即它们都是,例如,迭代(即你可以写for element in container: )。 (他们没有直接继承关系的事实是无关紧要的。)



Answer 5:

我写我在Python 3.2.1答案。

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

这个怎么运作:

  1. overload需要可调用的任何量和将它们存储在元组functions ,然后返回拉姆达。
  2. 拉姆达需要的参数中的任何量,然后返回调用存储在函数的结果functions[number_of_unnamed_args_passed]调用传递给拉姆达参数。

用法:

class A:
    stackoverflow=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) \
    )


Answer 6:

我想你要找的是“超载”这个词。 有没有方法在Python超载。 然而,你可以使用默认参数,如下所示。

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

当你传递一个自变量,它会按照第一个条件的逻辑和执行第一条print语句。 当你通过它没有参数,它会进入else条件,并执行第二个print语句。



Answer 7:

我写我在Python 2.7的答案:

在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


Answer 8:

在Python,超载不是所施加的概念。 但是,如果你想创造一个,比如,你想如果传递类型的参数来进行一个初始化的情况下, foo而另一个初始化为类型的参数bar ,然后,因为在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'
         ...

此概念可通过不同的方法根据需要被施加到多个不同的场景。



Answer 9:

在Python中,你会用默认参数做到这一点。

class A:

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


Answer 10:

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

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.

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.



Answer 11:

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 sum method
sum(4, 5, 5)

我们需要提供可选的参数或* ARGS,以提供关于调用不同数量的参数的个数。

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



Answer 12:

虽然@agf是正确的,在过去的答案现在PEP-3124 ,我们得到了我们的语法sugger。 请参阅有关详细信息,键入文档的@overload装饰,但请注意,这真的只是语法sugger恕我直言,这是至今所有的人一直争论。 我个人认为,具有不同特征的多个功能,使它更具可读性则具有20+所有参数设置为默认值(单个功能None大部分的时间),然后不得不反复折腾使用无尽ifelifelse链找出主叫方实际上想要我们的功能与所提供的参数集做。 这,这是早就应该遵循的Python禅

美丽的比丑好。

按理说也

简单比复杂好。

直接从官方Python文档上面链接:

@overload
def process(response: None) -> None:
    ...
@overload
def process(response: int) -> Tuple[int, str]:
    ...
@overload
def process(response: bytes) -> str:
    ...
def process(response):
    <actual implementation>


Answer 13:

蟒3.x的包括标准打字库,其允许方法与使用@overload装饰的过载。 不幸的是,这是为了让代码更易读,因为@overload装饰方法将需要其次是处理不同参数的非装饰方法。 更可以在这里找到这里 ,但你的例子:

from typing import overload
from typing import Any, Optional
class A(object):
    @overload
    def stackoverflow(self) -> None:    
        print('first method')
    @overload
    def stackoverflow(self, i: Any) -> None:
        print('second method', i)
    def stackoverflow(self, i: Optional[Any] = None) -> None:
        if not i:
            print('first method')
        else:
            print('second method', i)

ob=A()
ob.stackoverflow(2)


Answer 14:

在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

在Main.py文件

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

我们可以通过使用multipledispatch重载方法



文章来源: How do I use method overloading in Python?