如何在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 <module> ob.stackoverflow() TypeError: stackoverflow() takes exactly 2 arguments (1 given)
我该如何做这项工作?
这是方法重载而不是方法重写 。 而在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中新的单个分派generics函数的信息。
在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
你不能,永远不需要,也不会真的想要。
在Python中,一切都是一个对象。 类是事物,所以它们是物体。 方法也是如此。
有一个叫A
的对象是一个类。 它有一个名为stackoverflow
的属性。 它只能有一个这样的属性。
当你编写def stackoverflow(...): ...
,会发生什么是你创build一个对象,这是该方法,并将其分配给A
的stackoverflow
属性。 如果你写两个定义,第二个取代第一个,就像分配总是performance一样。
此外,你不想编写那些有时用于重载的types的代码。 这不是语言的工作原理。 不要试图为每种types的东西定义一个单独的函数(这没什么意义,因为你不必为函数参数指定types), 不要再担心什么是事情, 而是开始思考他们能做什么 。 你不但不能单独编写一个元组来处理一个元组,而且也不需要或不需要 。 你所要做的就是充分利用它们都是可迭代的(即你可以for element in container:
写入for element in container:
:)。 (它们与inheritance没有直接关系的事实是无关紧要的。)
我想你正在寻找的词是“超载”。 在Python中没有方法重载。 但是,您可以使用默认参数,如下所示。
def stackoverflow(self, i=None): if i != None: print 'second method', i else: print 'first method'
当你传递一个参数时,它将遵循第一个条件的逻辑并执行第一个打印语句。 当你传递它没有参数时,它将进入else
条件并执行第二个打印语句。
你也可以使用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 2.7编写我的答案:
在Python中,方法重载是不可能的。 如果你真的想访问不同的function相同的function,我build议你去方法重写。
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中,你可以用默认参数来做这件事。
class A: def stackoverflow(self, i=None): if i == None: print 'first method' else: print 'second method',i
我用Python 3.2.1编写我的答案。
def overload(*functions): return lambda *args, **kwargs: functions[len(args)](*args, **kwargs)
怎么运行的:
-
overload
可以将任意数量的可调用functions
和存储在元组functions
,然后返回lambda。 - lambda获取任意数量的参数,然后返回存储在传递给lambda的argmuments所调用的
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) \ )
在Python中,重载不是一个应用的概念。 然而,如果你想创build一个案例,例如,如果你想要一个初始化器被执行,如果传递了一个types为foo
的参数和另一个types为bar
的参数的初始化器,那么,因为Python中的所有东西都被当作对象来处理,可以检查传递的对象的类types的名称,并根据它写出有条件的处理。
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' ...
这个概念可以根据需要通过不同的方法应用于多个不同的场景。
刚刚遇到这个https://github.com/bintoro/overloading.py任何人可能有兴趣。;
从链接库的自述文件:
重载是一个根据运行时参数的types和数量提供函数调度的模块。
调用重载函数时,调度程序会将提供的参数与可用函数签名进行比较,并调用提供最准确匹配的实现。
特征
注册时的functionvalidation和详细的解决scheme规则保证了运行时的独特,定义明确的结果。 实现function分辨率caching以获得更好的性能。 支持function签名中的可选参数(默认值)。 在解决最佳匹配时,计算位置和关键字参数。 支持后备function和执行共享代码。 支持参数多态性。 支持类和inheritance,包括类方法和静态方法。