python类函数重载,class - 如何在Python中使用方法重载?

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值