use*_*578 147 python overloading class
我试图在Python中实现方法重载:
class A:
def stackoverflow(self):
print 'first method'
def stackoverflow(self, i):
print 'second method', i
ob=A()
ob.stackoverflow(2)
Run Code Online (Sandbox Code Playgroud)
但输出是second method 2; 类似的:
class A:
def stackoverflow(self):
print 'first method'
def stackoverflow(self, i):
print 'second method', i
ob=A()
ob.stackoverflow()
Run Code Online (Sandbox Code Playgroud)
给
Traceback (most recent call last):
File "my.py", line 9, in <module>
ob.stackoverflow()
TypeError: stackoverflow() takes exactly 2 arguments (1 given)
Run Code Online (Sandbox Code Playgroud)
我该如何工作?
agf*_*agf 139
它的方法是重载而不是方法重写.在Python中,您可以在一个函数中完成所有操作:
class A:
def stackoverflow(self, i='some_default_value'):
print 'only method'
ob=A()
ob.stackoverflow(2)
ob.stackoverflow()
Run Code Online (Sandbox Code Playgroud)
你不能在Python中有两个同名的方法 - 你不需要.
请参阅Python教程的Default Argument Values部分.有关要避免的常见错误,请参阅"最小惊讶"和可变默认参数.
编辑:有关Python 3.4中新的单一调度泛型函数的信息,请参阅PEP 443.
Ehs*_*ian 48
你也可以使用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
Run Code Online (Sandbox Code Playgroud)
Chr*_*gan 46
在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'
Run Code Online (Sandbox Code Playgroud)
如您所见,您可以使用它来触发单独的行为,而不仅仅是具有默认值.
>>> ob = A()
>>> ob.stackoverflow()
first form
>>> ob.stackoverflow(2)
second form
Run Code Online (Sandbox Code Playgroud)
Kar*_*tel 24
你不能,永远不需要也不想真的.
在Python中,一切都是对象.类是事物,所以它们是对象.方法也是如此.
有一个叫做A类的对象.它有一个名为的属性stackoverflow.它只能有一个这样的属性.
当您编写时def stackoverflow(...): ...,会发生的是您创建一个方法对象,并将其分配给该stackoverflow属性A.如果您编写两个定义,则第二个定义将替换第一个定义,与分配始终表现的方式相同.
此外,您不希望编写的代码可以解决有时用于重载的各种事物.这不是语言的运作方式.
而不是试图为每种类型的事物定义一个单独的函数(由于你没有指定函数参数的类型,这没什么意义),不要再担心事情是什么,并开始考虑他们可以做什么.
你不仅不能写一个单独的处理元组与列表,而且也不想要或不需要.
你要做的只是利用它们都是可迭代的事实(即你可以写for element in container:).(它们与继承没有直接关系的事实是无关紧要的.)
Gin*_*lus 16
我在Python 3.2.1中写了我的答案.
def overload(*functions):
return lambda *args, **kwargs: functions[len(args)](*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
这个怎么运作:
overload获取任意数量的callables并将它们存储在元组中functions,然后返回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) \
)
Run Code Online (Sandbox Code Playgroud)
may*_*ewr 14
我认为你要找的那个词是"超载".python中没有方法重载.但是,您可以使用默认参数,如下所示.
def stackoverflow(self, i=None):
if i != None:
print 'second method', i
else:
print 'first method'
Run Code Online (Sandbox Code Playgroud)
当你传递一个参数时,它将遵循第一个条件的逻辑并执行第一个print语句.当你传递没有参数时,它将进入else条件并执行第二个print语句.
Moo*_*thu 13
我在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
Run Code Online (Sandbox Code Playgroud)
在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'
...
Run Code Online (Sandbox Code Playgroud)
这个概念可以根据需要通过不同的方法应用于多个不同的场景.
python 3.5添加了打字模块。这包括一个重载装饰器。
该装饰器的预期目的是帮助类型检查器。从功能上来说,它只是鸭子打字。
from typing import Optional, overload
@overload
def foo(index: int) -> str:
...
@overload
def foo(name: str) -> str:
...
@overload
def foo(name: str, index: int) -> str:
...
def foo(name: Optional[str] = None, index: Optional[int] = None) -> str:
return f"name: {name}, index: {index}"
foo(1)
foo("bar", 1)
foo("bar", None)
Run Code Online (Sandbox Code Playgroud)
这导致 VS Code 中出现以下类型信息:
虽然这会有所帮助,但请注意,这会添加许多“奇怪的”新语法。它的目的——纯粹的类型提示——并不是立即显而易见的。
使用类型联合通常是更好的选择。
在Python中,您可以使用默认参数执行此操作.
class A:
def stackoverflow(self, i=None):
if i == None:
print 'first method'
else:
print 'second method',i
Run Code Online (Sandbox Code Playgroud)
虽然@agf过去在PEP-3124上的答案是正确的,但我们得到了语法建议。有关装饰器的详细信息 ,请参见键入文档。@overload但是请注意,这实际上只是语法建议,恕我直言,这是此后所有人一直在争论的话题。我个人认为,具有不同特征的多个功能,使它更具可读性则具有20+的参数都设置为默认值(单个功能None的大部分时间),然后不得不反复折腾使用不已if,elif,else链找出什么调用者实际上希望我们的函数处理提供的参数集。在Python Zen之后,这早就该了
美丽胜于丑陋。
而且也可以说
简单胜于复杂。
直接来自上面链接的官方Python文档:
from typing import overload
@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>
Run Code Online (Sandbox Code Playgroud)
刚刚遇到这个https://github.com/bintoro/overloading.py给任何可能感兴趣的人.
从链接存储库的自述文件中:
重载是一个模块,它根据运行时参数的类型和数量提供函数调度.
当调用重载函数时,调度程序将提供的参数与可用函数签名进行比较,并调用提供最准确匹配的实现.
特征
注册时的功能验证和详细的解决规则可确保在运行时获得独特,明确的结果.实现功能解析缓存以获得出色的性能.支持函数签名中的可选参数(默认值).在解析最佳匹配时评估位置和关键字参数.支持回退功能和共享代码的执行.支持参数多态性.支持类和继承,包括classmethods和staticmethods.
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)
Run Code Online (Sandbox Code Playgroud)
我们需要提供可选参数或 *args 以便在调用时提供不同数量的参数。
| 归档时间: |
|
| 查看次数: |
175940 次 |
| 最近记录: |