class - 如何在Python中使用方法重载?
我试图在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
ob.stackoverflow()
TypeError: stackoverflow() takes exactly 2 arguments (1 given)
我该如何工作?
14个解决方案
129 votes
它的方法是重载而不是方法重写。 在Python中,您可以在一个函数中完成所有操作:
class A:
def stackoverflow(self, i='some_default_value'):
print 'only method'
ob=A()
ob.stackoverflow(2)
ob.stackoverflow()
你不能在Python中有两个同名的方法 - 你不需要。
请参阅Python教程的Default Argument Values部分。 有关要避免的常见错误,请参阅“最小惊讶”和可变默认参数。
编辑:有关Python 3.4中新的单一调度泛型函数的信息,请参阅PEP 443。
agf answered 2019-05-30T16:58:43Z
45 votes
在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
Chris Morgan answered 2019-05-30T16:59:16Z
30 votes
你也可以使用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
Ehsan Keshavarzian answered 2019-05-30T16:59:42Z
27 votes
你不能,永远不需要也不想真的。
在Python中,一切都是对象。 类是事物,所以它们是对象。 方法也是如此。
有一个名为for element in container:的对象是一个类。 它有一个名为stackoverflow的属性。它只能有一个这样的属性。
当您编写for element in container:时,会发生的情况是您创建一个方法对象,并将其分配给stackoverflow属性A.如果您编写两个定义,则第二个定义将替换第一个定义,与分配始终表现的方式相同。
此外,您不希望编写的代码可以解决有时用于重载的各种事物。 这不是语言的运作方式。
而不是试图为每种类型的事物定义一个单独的函数(因为你没有指定函数参数的类型,这没什么意义),不要再担心事情是什么,并开始考虑他们可以做什么。
你不仅不能写一个单独的处理元组与列表,而且也不想要或不需要。
你所做的只是利用它们都是可迭代的事实(即你可以写for element in container:)。 (它们与继承没有直接关系的事实是无关紧要的。)
Karl Knechtel answered 2019-05-30T17:00:58Z
16 votes
我在Python 3.2.1中写了我的答案。
def overload(*functions):
return lambda *args, **kwargs: functions[len(args)](*args, **kwargs)
这个怎么运作:
functions[number_of_unnamed_args_passed]获取任意数量的callables并将它们存储在元组functions中,然后返回lambda。
lambda需要任意数量的参数,然后返回存储在functions[number_of_unnamed_args_passed]中的调用函数的结果,并调用传递给lambda的参数。
用法:
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) \
)
GingerPlusPlus answered 2019-05-30T17:01:43Z
12 votes
我认为你要找的那个词是“超载”。 python中没有方法重载。 但是,您可以使用默认参数,如下所示。
def stackoverflow(self, i=None):
if i != None:
print 'second method', i
else:
print 'first method'
当你传递一个参数时,它将遵循第一个条件的逻辑并执行第一个print语句。 当你传递没有参数时,它将进入else条件并执行第二个print语句。
mayhewr answered 2019-05-30T17:02:18Z
12 votes
我在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
Moorthi Muthu answered 2019-05-30T17:02:52Z
9 votes
在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'
...
这个概念可以根据需要通过不同的方法应用于多个不同的场景。
S. Gamgee answered 2019-05-30T17:03:26Z
7 votes
在Python中,您可以使用默认参数执行此操作。
class A:
def stackoverflow(self, i=None):
if i == None:
print 'first method'
else:
print 'second method',i
John Gaines Jr. answered 2019-05-30T17:03:54Z
5 votes
对于任何可能感兴趣的人来说,只是遇到了这个[https://github.com/bintoro/overloading.py]。
从链接存储库的自述文件中:
重载是一个基于提供函数调度的模块 运行时参数的类型和数量。
当调用重载函数时,调度程序会比较 提供可用函数签名的参数并调用 提供最准确匹配的实现。
特征
注册时的功能验证和详细的解决规则 在运行时保证唯一,明确定义的结果。器物 功能解析缓存以获得出色的性能。 支持可选 函数签名中的参数(默认值)。 评估两者 解决最佳匹配时的位置和关键字参数。 支持回退功能和共享代码的执行。支持 参数多态性。 支持类和继承,包括 classmethods和staticmethods。
Mark Lawrence answered 2019-05-30T17:04:53Z
3 votes
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,以便在调用时提供不同数量的args。
礼貌来自[https://www.geeksforgeeks.org/python-method-overloading/]
Atihska answered 2019-05-30T17:05:34Z
2 votes
虽然@agf过去对PEP-3124的答案是正确的,但我们得到了我们的语法。 请参阅键入文档以获取有关@overload装饰器的详细信息,但请注意,这实际上只是语法sugger和恕我直言,这是所有人一直在争论的。 个人而言我同意具有不同签名的多个函数使其更具可读性,然后将具有20多个参数的单个函数全部设置为默认值(大部分时间为None),然后不得不使用无穷无尽的if,elif,elsechains来摆弄 找出调用者实际上希望我们的函数与提供的参数集做什么。 这是Python Zen之后的姗姗来迟
美丽胜过丑陋。
并且可以说也是
简单比复杂更好。
直接上面链接的官方Python文档:
@overload
def process(response: None) -> None:
...
@overload
def process(response: int) -> Tuple[int, str]:
...
@overload
def process(response: bytes) -> str:
...
def process(response):
masi answered 2019-05-30T17:06:22Z
1 votes
Python 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)
nickthefreak answered 2019-05-30T17:06:51Z
0 votes
在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重载方法
Mahabubuzzaman answered 2019-05-30T17:07:34Z