在python中使用相同签名重载的方法

时间:2015-11-18 07:28:19

标签: python python-2.7 python-3.x overloading

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

这是一个包含三个方法的类,它们都具有相同的名称(甚至相同的签名)

当我这样称呼时:

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)

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

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

2 个答案:

答案 0 :(得分:2)

  

那么我可以假设在这种情况下它总会在类中执行最后一个方法吗?

你做对了。你的第一个例子相当于:

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

答案 1 :(得分:2)

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

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

python中没有方法重载,因为我们有那些很好的关键字参数,允许我们进行'重载'调用,但是我们需要它们:

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社区。