【问题标题】:Is it legal to define two methods with the same name but different returning types?定义两个具有相同名称但返回类型不同的方法是否合法?
【发布时间】:2021-01-06 21:37:32
【问题描述】:

我编写了一段代码来确定一个典型的回文字符串。我通过定义返回字符串的 reverse() 方法来做到这一点。我也很渴望有同样的方法,不过是虚空形式,因为以后有一些需要。

当我将后者添加到代码中时,有效的输出将变得无效。定义两个同名但返回类型不同的方法是否合法?

如果没有,我该如何用void类型的方法编写这段代码?

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

当我添加注释掉的行时,有效的“是”变为“否”!

【问题讨论】:

标签: python


【解决方案1】:

这样写是合法的,但它没有定义两种方法。最后一个定义覆盖了第一个,所以只有最后一个存在并且总是会调用那个。就像你做的一样

x = 1
x = 2

第一个任务被第二个所抹杀。

至于您的更大问题:拥有两个返回不同事物的方法的方法是定义两个具有不同名称的方法。 Python 对函数“打算”返回的类型一无所知。没有所谓的“空类型方法”。

【讨论】:

    【解决方案2】:

    如果您调用两个方法,Python 将覆盖第一个创建的方法,只保留第二个定义:

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

    基本上,第二个覆盖第一个。

    要了解为什么 Python 会这样做,请从常识的角度来看。假设您有一个在线作业,当您完成它时,有两个同名的作业。你怎么知道该选哪一个?基本上,Python 只会选择最近的一个,这是明智的选择。

    另外,在调用函数时认为 Python 会如何理解如果它们都具有相同的名称,你想要哪一个?

    Python 可能是一门聪明的语言,但绝不是通灵的 :)

    【讨论】:

    • 说 Python 在您 调用 时不知道选择哪个是误导。当你打电话给它的时候,已经没有选择了。在您进行第二个定义时,第一个定义被覆盖,并且无法取回或使用它。不仅仅是最后定义的那个是被调用的;相反,最后定义的那个是唯一存在的可以调用的。
    • @aj8uppal:谢谢。假设我重命名了第二种方法。您能指导我通过void方法解决解决方案吗?我的是字符串类型的...!
    • @matinking 解决解决方案究竟是什么意思?
    • @aj8uppal:我得到了上面代码的输出。我需要使用注释方法的有效输出,而不是我的字符串类型函数。
    【解决方案3】:

    如前所述,如果您在类中定义第二个方法,则第二个定义会覆盖第一个定义,剩下的就是第二个。

    但是,您可以拥有同名的函数和方法。试试这个:

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

    现在您有一个名为reverse 的函数和一个名为reverse 的方法,您可以像sortedsort 一样将它们用于列表:

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

    将此与排序列表进行比较:

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

    鉴于这反映了一种内置策略,这可能是要走的路。

    【讨论】:

    • 内置策略是让reverse() 进行就地编辑,reversed() 返回一个反向副本。
    • @Rob Watts:答案听起来很神奇......事实上,正如您在上面说明的那样,我对“方法”和“功能”的区别感到不知所措。因为,我认为这两个概念是相同的......
    • @matinking 他们很相似。 Here 是一个 StackOverflow 问题,讨论差异。基本上,方法是附加到一个类或实例上的,而函数则不是。
    • @Rob Watts:你说得很对。感谢您的指导。
    【解决方案4】:

    没有。 Python does not have method/function overloading,这是这种区分操作(在调用级别)的先决条件,这反过来又允许“两个同名的方法”。

    在具有重载的语言中,通常是静态类型的,通常禁止返回类型是唯一的鉴别器,甚至是不同的 - 这样做需要结果表达式的用法被考虑在内。

    就这个特殊问题而言,我只是不包括“无效形式”。如果需要这种情况,请将其设为一个不同的方法(根据上述限制使用唯一名称),以明确目标只是没有可用结果的副作用:例如,将 sorted 的名称与list.sort.

    【讨论】:

    • 感谢您的连贯澄清。
    【解决方案5】:

    不,这是不合法的; Python 怎么知道该调用哪一个?只需重命名其中一种方法即可。

    【讨论】:

    • 其实我会用这样的命名系统,就像重载的概念一样,对应其他的OOP语言,名字都是一样的。另外,我不知道如何细化代码中的代码void型函数的使用!
    • @matinking:大多数 OOP 语言不支持返回类型的重载;大多数只支持参数的重载,如果有的话。
    • @jwodder:也就是说不可能重载返回类型,对吧?!
    • 并非不可能,但设计这种语言的好处通常大于坏处。参见例如stackoverflow.com/questions/442026/…,似乎至少 Perl 和 Haskell 支持它。
    【解决方案6】:

    您可以通过子类化来做到这一点:

    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
    

    现在,如果您实例化 x = weirdo('hey'),它的行为将是在您每次调用 x.reverse() 时永久反转其字符串值,而 detector 类的对象将继续像以前一样工作。

    (我让weirdo.reverse()也返回了新值,这样调用代码总是可以使用任何一种类型的对象。)

    我并不是特别推荐这个,只是演示一种方法。这很可能属于注释,但 cmets 不能真正包含 StackOverflow 上的代码。

    【讨论】:

    • 你在两个不同的类中解决了这个问题。实际上,这个案例需要在一个类的操作下考虑。
    • 也许你能解释一下为什么你有这样的约束?这是拥有类的主要原因之一——调用者不需要知道对象的确切类型,只需相信它以适合该对象的方式实现了我们调用的方法。
    • 但正如我在另一条评论中所指出的,简单的解决方法是拥有reversereversed,就像Pyrhon 拥有sortsorted。这实际上是我推荐的。
    • 解析的方法可以认为是一个函数和一个方法的使用,它们的名字是一样的。这种方法在一个操作作为有界方法负责计算一些东西并返回最终值的情况下是必不可少的。但考虑到大型项目中的有效编码,可能需要对某些庞大的对象具有相同的功能。在这种情况下,她将函数放在该类中,以便将通过方法和函数实现的两个相似的功能放在一个独特的地方。否则,你是对的。
    猜你喜欢
    • 2013-02-28
    • 1970-01-01
    • 2020-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多