Python中的@overload装饰器

Python中的@overload装饰器

1. 重写(override)与重载(overload)

在静态语言Java中有重写(override)和重载(overload)两个概念。其中重写是指子类对父类中允许访问的方法进行重新编写,重写时方法名,返回值和参数的数目、类型都不能改变。而重载指的是在同一个类里面,方法名相同,但参数不同的两个方法。

1.1 Java中的重写

class Animal {
    public void quack() {
        
    }
}

class Duck extends Animal {
    public void quack() {
        System.out.println("GaGaGa!");
    }
}

1.2 Java中的重载

class Duck {
    public void quack() {
        System.out.println("GaGaGa!");
    }

    // 该方法是对上面quack方法的重载
    public void quack(String mark) {
        System.out.printf("GaGaGa! %s", mark);
    }
}

2. 一般情况下,Python不允许重载

一般情况下,Python是不允许重载的。以下面这个例子为例,虽然我们定义两个quack函数,但是在局部命名空间下,只有一个quack函数,即后一个quack函数,也就是说后一个函数覆盖了前一个函数。

def quack():
    print("Quack: ")

print(quack)

def quack(mark):
    print(f"Quack: {mark}")

print(quack)
print(locals())

局部命名空间内只有一个quack函数

在类内部也是这样,不允许方法重载,如

from attr import attr

class Duck:

    def quack(self):
        print("GaGaGa!")
    
    def quack(self, mark):
        print(f"GaGaGa: {mark}")

print(dir(Duck))

d = Duck()
# d.quack()         # 会报错
d.quack("I am a duck~") # Output: GaGaGa: I am a duck~

Duck类中只有一个quack方法

3. overload装饰器

很多人认为只要在类方法中加上了@overload装饰器就实现了Python中的方法重载,实际上不是的。在官方文档中是这样介绍@overload装饰器的[1]

The@overloaddecorator allows describing functions and methods that support multiple different combinations of argument types. A series of@overload-decorated definitions must be followed by exactly one non-@overload-decorated definition (for the same function/method). The@overload-decorated definitions are for the benefit of the type checker only, since they will be overwritten by the non-@overload-decorated definition, while the latter is used at runtime but should be ignored by a type checker. At runtime, calling a@overload-decorated function directly will raiseNotImplementedError.

也就是说,和typing这module里面其他东西的功能一样,@overload装饰器其实只是一种注解/提示:该函数允许传入不同的参数类型组合。最终,所有加了@overload装饰器的方法都会被一个不加装饰器的方法覆盖掉。如

from typing import overload

class Duck:

    @overload
    def quack(self) -> None: ...

    @overload
    def quack(self, mark: str) -> None: ...

    # 以上两个方法最终会被这个方法覆盖掉
    def quack(self, arg=None):
        if arg:
            print(f"GaGaGa: {arg}")
        else:
            print("GaGaGa!")

d = Duck()
d.quack()                # Output: GaGaGa!
d.quack("I am a duck~")  # Output: GaGaGa: I am a duck~

《AUTOSAR谱系分解(ETAS工具链)》之总目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值