1

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"!

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Roboticist
  • 925
  • 1
  • 16
  • 32
  • Related (not duplicate): *[How can I detect duplicate method names in a Python class?](https://stackoverflow.com/questions/10761988)* – Peter Mortensen Jan 06 '21 at 13:39

6 Answers6

6

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

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
A.J. Uppal
  • 17,608
  • 6
  • 40
  • 70
  • 2
    To say that Python doesn't know which one to pick at the time you *call* it is misleading. By the time you call it, there is no choice to be made. At the time you make the second definition, the first one is overwritten and there is no way to get it back or make use of it. It's not just that the one defined last is the one called; rather, the one defined last is the only one that even exists to be called. – BrenBarn May 17 '14 at 04:53
  • @ aj8uppal: Thank you. Assume that I rename the second method. Would you guiding me to solve the solution by the void method. Mine is by the string-type one...! – Roboticist May 17 '14 at 04:55
  • 1
    @matinking what exactly do you mean by *solving the solution?* – A.J. Uppal May 17 '14 at 04:58
  • @ aj8uppal: I got the output with the above code. I need the valid output with utilization of the commented method, instead of my string-type function. – Roboticist May 17 '14 at 05:01
6

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".

BrenBarn
  • 210,788
  • 30
  • 364
  • 352
3

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.

Community
  • 1
  • 1
user2864740
  • 54,112
  • 10
  • 112
  • 187
3

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.

Rob Watts
  • 6,260
  • 2
  • 31
  • 57
  • 2
    The built-in strategy would be to have `reverse()` to do in-place editing and `reversed()` return a reversed copy. – tripleee May 17 '14 at 05:10
  • @Rob Watts:The answer sounds amazing... As a matter of fact, I am overwhelmed with the difference of "method" and "function", as you illustrated above. Because, I thought there are both the same concepts... – Roboticist May 17 '14 at 05:11
  • 1
    @matinking They're similar. [Here](http://stackoverflow.com/questions/11949808/what-is-the-difference-between-a-function-an-unbound-method-and-a-bound-method) is a StackOverflow question talking about the difference. Basically, methods are attached to a class or instance, and functions are not. – Rob Watts May 17 '14 at 05:15
  • @Rob Watts: You're considerably right. Appreciated due to your guidance. – Roboticist May 17 '14 at 05:17
2

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

jwodder
  • 46,316
  • 9
  • 83
  • 106
  • Actually I am going to use such naming system just like the overloading concept, corresponding to the other OOP languages, where the names are the same.Furthermore, I have no idea how to refine the code within the utilization of the void-type function! – Roboticist May 17 '14 at 04:52
  • 1
    @matinking: Most OOP languages do not support overloading on return type; most only support overloading on the arguments, if at all. – icktoofay May 17 '14 at 04:55
  • @jwodder: So mean that overloading on return type is impossible, right?! – Roboticist May 17 '14 at 04:58
  • Not impossible, but the benefits usually outweigh the downsides in designing such a language. See for example https://stackoverflow.com/questions/442026/function-overloading-by-return-type, it seems at least Perl and Haskell support it. – Dining Philosopher Mar 21 '19 at 14:09
1

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.

tripleee
  • 139,311
  • 24
  • 207
  • 268
  • You resolve the case within two different classes. The case needed to be considered just under operation of one class, actually. – Roboticist May 17 '14 at 05:22
  • Perhaps you can explain why you have a constraint like that? This is one of the main reasons to have classes -- the caller doesn't need to know the precise type of the object, just trust that it implements the method we call in a manner suitable for this object. – tripleee May 17 '14 at 07:21
  • But as noted in another comment of mine, the simple fix is to have `reverse` and `reversed` just like Pyrhon has `sort` and `sorted`. That's actually what I would recommend. – tripleee May 17 '14 at 07:23
  • The resolved approach might be considered as utilization of a function and a method, are which named the same. This approach in essential in the case that one operation, as a bounded method, is responsible for computing some stuff and return the final value. But in view of the effective coding in large projects, one might need to have the same functionality for some vast kind of objects. In this case, she puts the function one in that class in order to keep both similar functionalities, are which realized with the method and the function, in a unique place together. Otherwise, you're right. – Roboticist May 17 '14 at 07:39