简体   繁体   中英

Is it legal to define two methods with the same name but different returning types?

I've written a piece of code to determine a typical palindrome string. I did this by the definition of a reverse() method returning a string. I am also eager to have the same method, but in the void form, because of some future needs.

As I add the latter to the code, the valid output will become invalid. Is it legal to define two methods with the same name, but different returning types?

If not, how can I write this code with the void-type method?

class detector(object):
    def __init__(self,string):
        self.string = string

    forbidden = (' ','!','?','.','-','_','&','%',"#",",")

    def eliminator(self):
        for item in self.forbidden:
            if item in self.string:
                self.string = self.string.replace(item,"")

    def reverse(self):
        return self.string[::-1]

    #def reverse(self):
    #    self.string = self.string[::-1]    I am prone to add this method

    def check(self):
        reversed = self.reverse()
        if self.string == reversed:
            print("Yes")
        else:
            print("No")

det = detector("rise to vote, sir!")
det.eliminator()
det.check()

When I add the outcommented lines, the valid "Yes" becomes "No"!

If you call two methods, Python will override the first one made, leaving just the second one defined:

>>> def foo():
...     return 1
...
>>> def foo():
...     return 2
...
>>> foo()
2
>>>

Basically, the second one overrides the first.

To see why Python would do this, take it from a common sense standpoint . Say you have a homework assignment, which is online, and when you get to it, there are two assignments under the same name. How would you know which one to pick? Basically, Python just picks the most recent one, which is the smart choice.

Also, when calling the function , how do you think Python would understand which one you want if they both have the same name?

Python may be a smart language, but it is by no means psychic :)

It is legal to write that, but it doesn't define two methods. The last definition overwrites the first, so only the last one exists and that one will always be called. It is the same as if you did

x = 1
x = 2

The first assignment is obliterated by the second.

As for your larger question: The way to have two methods that return different things is to define two methods with different names. Python does not know anything about the types that a function "intends" to return. There is no such thing as a "void-type method".

No. Python does not have method/function overloading , which is a prerequisite for such a discriminating operation (at the invocation level), which in turn allows "two methods with the same name".

In languages with overloading, which are most often statically typed, it is generally prohibited for the return type to be the sole discriminator or even differ - doing so would require the usage of the resulting expression to be taken into account.

As far as this particular problem, I would simply not include the "void form". If such a case is needed, make it a distinct method (with a unique name per above restrictions) that makes it apparent that the goal is merely a side-effect without a usable result: for instance, compare the name of sorted with list.sort .

As has been pointed out, if you define a second method in a class, the second definition overwrites the first one and all that will be left is the second one.

However, you can have a function and a method with the same name. Try this:

def reverse(detector_object):
    return detector(detector_object.string[::-1])

class detector(object):
...
    def reverse(self):
        self.string = self.string[::-1]

Now you have a function called reverse and a method called reverse , and you would use them like sorted and sort for lists:

old_detector.reverse() # reverse it in place
new_detector = reverse(old_detector) # return a new detector object with the string reversed

Compare this to sorting a list:

my_list.sort() # sort list in place
new_list = sorted(my_list)

Seeing as this mirrors a built-in strategy, this is probably the way to go.

No, it's not legal; how would Python know which one to call? Just rename one of the methods.

You could do this by subclassing:

class detector(object):
    def __init__(self,string):
        self.string = string
    def reverse(self):
        return self.string[::-1]

class weirdo(detector):
    def reverse(self):
        self.string = self.string[::-1]
        return self.string

Now if you instantiate x = weirdo('hey') its behavior will be to permanently reverse its string value each time you call x.reverse() whereas objects of class detector will continue to work as before.

(I made weirdo.reverse() also return the new value, so that calling code can always use objects of either type.)

I'm not particularly recommending this, just demonstrating an approach. This would prooerly belong in a comment, but comments can't really contain code on StackOverflow.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM