python 中具有相同签名的方法重载

Method overloading with the same signature in python

class testClass(object):
    def test1(self):
        print "1"
    def test1(self):
        print "2"
    def test1(self):
        print "3"

这是一个 Class 包含三个具有相同名称(甚至相同签名)的方法

当我调用这个时:

tc = testClass()
tc.test1()

它没有抛出任何错误,而是简单地打印 3

再举一个例子:

class testClass(object):
    def test1(self, a, b):
        print "1"
    def test1(self, a):
        print "2"
    def test1(self, a, b, c):
        print "3"

如果我再次调用 tc.test1(),它会引发异常:

TypeError: test1() takes exactly 4 arguments (1 given)

那么我可以假设在这些情况下它将始终执行 class 中定义的最后一个方法吗?

PS: 我对文件中的各个函数进行了相同的尝试并得到了相同的结果,它执行了最后一个函数。

So can I assume that in these situation it will always execute last method in the class?

你没看错。你的第一个例子相当于:

x = 1
x = 2
x = 3
print x
>> 3

是的,当 Python 遇到 class 语句时,它会执行 def 语句,以便为随后的 class 命名空间创建正确的名称绑定(__dict__).

与 运行 interpeter 一样,重新定义的名称将失去其旧值;它被替换为 对该特定名称的最新分配。

python 中没有方法重载,因为我们有那些不错的关键字参数,可以让我们根据需要进行 'overloaded' 调用:

class A:
    def f(self, a, b=None, c=None, d=None):
        print(a, b, c, d, sep=" | ")


a = A()

a.f(1)
# out : 1 | None | None | None

a.f(1, 2)
# out : 1 | 2 | None | None

a.f(1, 2, 3)
# out : 1 | 2 | 3 | None

a.f(1, 2, 3, 4)
# out : 1 | 2 | 3 | 4

最后一点,仅仅因为 Python 没有为您提供固有的重载并不意味着您不能自己实现该功能。

经过一番搜索后,我在 this repo 中找到了一个很好的例子,它公开了一个 @overloaded@overloads(func) 装饰器用于重载函数:

from overloading import *

@overloaded
def f():
    return 'no args'

@overloads(f)
def f(foo):
    return 'one arg of any type'

@overloads(f)
def f(foo:int, bar:int):
    return 'two ints'

>>> f()
'no args'
>>> f('hello')
'one arg of any type'
>>> f('hello', 42)
TypeError: Invalid type or number of arguments when calling 'f'.

爱上 Python 社区。