in python you can_How do I use method overloading in Python?

问题

I am trying to implement method overloading in Python:

class A:

def stackoverflow(self):

print \'first method\'

def stackoverflow(self, i):

print \'second method\', i

ob=A()

ob.stackoverflow(2)

but the output is second method 2; similarly:

class A:

def stackoverflow(self):

print \'first method\'

def stackoverflow(self, i):

print \'second method\', i

ob=A()

ob.stackoverflow()

gives

Traceback (most recent call last):

File \"my.py\", line 9, in

ob.stackoverflow()

TypeError: stackoverflow() takes exactly 2 arguments (1 given)

How do I make this work?

回答1:

It's method overloading not method overriding. And in Python, you do it all in one function:

class A:

def stackoverflow(self, i='some_default_value'):

print 'only method'

ob=A()

ob.stackoverflow(2)

ob.stackoverflow()

You can't have two methods with the same name in Python -- and you don't need to.

See the Default Argument Values section of the Python tutorial. See "Least Astonishment" and the Mutable Default Argument for a common mistake to avoid.

Edit: See PEP 443 for information about the new single dispatch generic functions in Python 3.4.

回答2:

You can also use 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

回答3:

In Python, you don't do things that way. When people do that in languages like Java, they generally want a default value (if they don't, they generally want a method with a different name). So, in Python, you can have default values.

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'

As you can see, you can use this to trigger separate behaviour rather than merely having a default value.

>>> ob = A()

>>> ob.stackoverflow()

first form

>>> ob.stackoverflow(2)

second form

回答4:

You can't, never need to and don't really want to.

In Python, everything is an object. Classes are things, so they are objects. So are methods.

There is an object called A which is a class. It has an attribute called stackoverflow. It can only have one such attribute.

When you write def stackoverflow(...): ..., what happens is that you create an object which is the method, and assign it to the stackoverflow attribute of A. If you write two definitions, the second one replaces the first, the same way that assignment always behaves.

You furthermore do not want to write code that does the wilder of the sorts of things that overloading is sometimes used for. That's not how the language works.

Instead of trying to define a separate function for each type of thing you could be given (which makes little sense since you don't specify types for function parameters anyway), stop worrying about what things are and start thinking about what they can do.

You not only can't write a separate one to handle a tuple vs. a list, but also don't want or need to.

All you do is take advantage of the fact that they are both, for example, iterable (i.e. you can write for element in container:). (The fact that they aren't directly related by inheritance is irrelevant.)

回答5:

I write my answer in Python 3.2.1.

def overload(*functions):

return lambda *args, **kwargs: functions[len(args)](*args, **kwargs)

How it works:

overload takes any amount of callables and stores them in tuple functions, then returns lambda.

The lambda takes any amount of arguments,

then returns result of calling function stored in functions[number_of_unnamed_args_passed] called with arguments passed to the lambda.

Usage:

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) \

)

回答6:

I think the word you're looking for is "overloading". There is no method overloading in python. You can however use default arguments, as follows.

def stackoverflow(self, i=None):

if i != None:

print 'second method', i

else:

print 'first method'

When you pass it an argument it will follow the logic of the first condition and execute the first print statement. When you pass it no arguments, it will go into the else condition and execute the second print statement.

回答7:

I write my answer in Python 2.7:

In Python, method overloading is not possible; if you really want access the same function with different features, I suggest you to go for method overriding.

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

回答8:

In Python, overloading is not an applied concept. However, if you are trying to create a case where, for instance, you want one initializer to be performed if passed an argument of type foo and another initializer for an argument of type bar then, since everything in Python is handled as object, you can check the name of the passed object's class type and write conditional handling based on that.

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'

...

This concept can be applied to multiple different scenarios through different methods as needed.

回答9:

In Python, you'd do this with a default argument.

class A:

def stackoverflow(self, i=None):

if i == None:

print 'first method'

else:

print 'second method',i

回答10:

While @agf was right with the answer in the past now with PEP-3124 we got our syntax sugger. See typing documentation for details on the @overload decorator but note that this is really just syntax sugger and IMHO this is all people have been arguing about ever since. Personally I agree that having multiple functions with different signatures makes it more readable then having a single function with 20+ arguments all set to a default value (None most of the time) and then having to fiddle around using endless if, elif, elsechains to find out what the caller actually wants our function to do with the provided set of arguments. This was long overdue following the Python Zen

Beautiful is better than ugly.

and arguably also

Simple is better than complex.

Straight from the official Python documentation linked above:

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):

回答11:

Just came across this https://github.com/bintoro/overloading.py for anybody who may be interested.

From the linked repository's readme:

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.

回答12:

Python does not support method overloading like Java or C++. We may overload the methods but can only use the latest defined method.

# 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)

We need to provide optional arguments or *args in order to provide different number of args on calling.

Courtesy from https://www.geeksforgeeks.org/python-method-overloading/

回答13:

Python 3.x includes standard typing library which allows for method overloading with the use of @overload decorator. Unfortunately, this is to make the code more readable, as the @overload decorated methods will need to be followed by a non-decorated method that handles different arguments.

More can be found here here but for your example:

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)

回答14:

In MathMethod.py file

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

In Main.py file

import MathMethod as MM

print(MM.Add(200,1000,1000,200))

We can overload method by using multipledispatch

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值