How do I use method overloading in Python?
我尝试在python中实现方法重载:
1 2 3 4 5 6 7 8 | class A: def stackoverflow(self): print 'first method' def stackoverflow(self, i): print 'second method', i ob=A() ob.stackoverflow(2) |
但是输出是
1 2 3 4 5 6 7 8 | class A: def stackoverflow(self): print 'first method' def stackoverflow(self, i): print 'second method', i ob=A() ob.stackoverflow() |
给予
1 2 3 4 | Traceback (most recent call last): File"my.py", line 9, in <module> ob.stackoverflow() TypeError: stackoverflow() takes exactly 2 arguments (1 given) |
我该怎么做?
它是方法重载,而不是方法重写。在Python中,您可以在一个函数中完成所有操作:
1 2 3 4 5 6 7 8 | class A: def stackoverflow(self, i='some_default_value'): print 'only method' ob=A() ob.stackoverflow(2) ob.stackoverflow() |
在Python中,不能有两个同名的方法——而且不需要这样做。
请参见Python教程的"默认参数值"部分。请参阅"最小惊异"和可变默认参数,了解要避免的常见错误。
编辑:有关python 3.4中新的单分派通用函数的信息,请参阅pep 443。
在python中,您不会这样做。当人们用Java语言这样做时,他们通常想要一个默认值(如果他们不这样,他们通常需要一个不同名称的方法)。所以,在python中,可以有默认值。
1 2 3 4 5 6 7 | 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' |
如您所见,您可以使用它来触发单独的行为,而不仅仅是拥有一个默认值。
1 2 3 4 5 | >>> ob = A() >>> ob.stackoverflow() first form >>> ob.stackoverflow(2) second form |
您也可以使用pythonlangutil:
1 2 3 4 5 6 7 8 9 10 11 12 | 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 decorator。
你不能,不需要,也不想。
在Python中,一切都是一个对象。类是事物,所以它们是对象。方法也是如此。
有一个名为
当您编写
此外,您不希望编写代码来执行有时使用重载的更疯狂的事情。这不是语言的工作方式。
不要试图为每种类型的对象定义一个单独的函数(这是毫无意义的,因为您无论如何都不为函数参数指定类型),不要担心这些对象是什么,开始考虑它们可以做什么。
您不仅不能编写单独的一个来处理元组和列表,而且也不想或不需要。
你所做的就是利用它们都是不可更改的这一事实(例如,你可以写
我用python 3.2.1编写了我的答案。
1 2 | def overload(*functions): return lambda *args, **kwargs: functions[len(args)](*args, **kwargs) |
它是如何工作的:
用途:
1 2 3 4 5 6 7 | 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) \ ) |
我认为你要找的词是"超载"。在Python中没有方法重载。但是,您可以使用默认参数,如下所示。
1 2 3 4 5 | def stackoverflow(self, i=None): if i != None: print 'second method', i else: print 'first method' |
当您传递一个参数时,它将遵循第一个条件的逻辑并执行第一个print语句。当您没有参数传递它时,它将进入
我用python 2.7写了我的答案:
在Python中,方法重载是不可能的;如果您真的想要访问具有不同特性的同一个函数,我建议您进行方法重写。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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 |
在Python中,重载不是一个应用的概念。但是,如果您试图创建这样一种情况:例如,如果传递了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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' ... |
这个概念可以根据需要通过不同的方法应用到多个不同的场景中。
在python中,您可以使用默认参数来实现这一点。
1 2 3 4 5 6 7 | class A: def stackoverflow(self, i=None): if i == None: print 'first method' else: print 'second method',i |
刚刚看到这个https://github.com/bintoro/overloading.py给任何可能感兴趣的人。
从链接存储库的自述文件中:
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.
虽然@agf过去对pep-3124的回答是正确的,但我们得到了语法建议。有关
Beautiful is better than ugly.
也可以说
Simple is better than complex.
直接从上面链接的官方python文档:
1 2 3 4 5 6 7 8 9 10 | @overload def process(response: None) -> None: ... @overload def process(response: int) -> Tuple[int, str]: ... @overload def process(response: bytes) -> str: ... def process(response): |
Python不支持像Java或C++那样的方法重载。我们可以重载这些方法,但只能使用最新定义的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # 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) |
我们需要提供可选参数或*参数,以便在调用时提供不同数量的参数。
由https://www.geeksforgeks.org/python-method-overloading提供/
python 3.x包含标准类型库,允许使用@overload decorator进行方法重载。不幸的是,这是为了提高代码的可读性,因为@overload修饰方法后面需要有一个处理不同参数的非修饰方法。在这里可以找到更多,但是对于您的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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) |
在mathmethod.py文件中
1 2 3 4 5 6 7 8 9 10 | 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文件
1 2 | import MathMethod as MM print(MM.Add(200,1000,1000,200)) |
我们可以使用multipledispatch来重载方法