wordpress仿站header,专门做团购的网站,重庆市工程建筑造价信息网,福田庆三下巴引言
说到函数重载#xff0c;学过 Java 的同学应该不陌生#xff0c;最常用的地方应该就是打印 log 了#xff0c;对于不同的参数#xff0c;调用的是不同的重载函数。那么 Python 如何实现函数重载呢#xff1f; 重载概念
函数重载是指在同一作用域内#xff0c;允许…引言
说到函数重载学过 Java 的同学应该不陌生最常用的地方应该就是打印 log 了对于不同的参数调用的是不同的重载函数。那么 Python 如何实现函数重载呢 重载概念
函数重载是指在同一作用域内允许多个同名函数存在但它们的参数列表不同。虽然许多编程语言如 Java 和 C支持函数重载但 Python 的设计哲学使其不能直接支持这一特性。
不使用重载
先看一个例子在不使用重载的情况下实现一个 log 函数
from attr import dataclassdataclass
class MyException(Exception):msg: strdef log(message):if isinstance(message, MyException):print(message.msg)elif isinstance(message, str):print(message)else:print(finvalid message:{message})log(MyException(my exception))
log(str exception)
log(1111)# 运行结果为
# my exception
# str exception
# invalid message:1111不使用重载的话就要写很多判断的代码来判断入参的类型。
使用重载
from functools import singledispatchfrom attr import dataclassdataclass
class MyException(Exception):msg: strsingledispatch
def log(message):print(finvalid message:{message})log.register
def _(message: MyException):print(message.msg)log.register
def _(message: str):print(message)log(MyException(my exception))
log(str exception)
log(1111)# 运行结果为
# my exception
# str exception
# invalid message:1111通过以上代码可以看到使用重载的情况下代码简洁了很多将之前的 if-else 判断都去掉了每个重载函数根据对应的类型直接输出对应的日志说明在调用函数时会自动判断函数的参数类型然后调用对应的重载函数来执行对应的逻辑。
如果有新增类型的需求只需要在原有的基础上增加一个重载函数即可大大简化了新增类型的难度。例如
from functools import singledispatchfrom attr import dataclassdataclass
class MyException(Exception):msg: strsingledispatch
def log(message):print(finvalid message:{message})log.register
def _(message: MyException):print(message.msg)log.register
def _(message: str):print(message)log.register
def _(message: int):print(fint message:{message})log(MyException(my exception))
log(str exception)
log(1111)# 运行结果为
# my exception
# str exception
# int message:1111重载写法
通过以上的代码总结 Python 通过 functools.singledispatch 进行重载的写法。
首先定义一个函数加上 singledispatch 装饰器然后添加几个以下划线为函数名的函数因为重载函数的名字都一样没有必要起其他的名字用下划线代替即可。为下划线函数设置对应的函数参数类型编写函数内容。调用函数来测试是否生效。
数据类
可能会有小伙伴问自定义异常上有一个 dataclass 装饰器这个是干嘛用的为什么没有写 __init__() 函数。
这个装饰器是Python3.6 中新引入的一个概念熟悉 Java 的小伙伴可能会知道它有点类似于 Java 中的 lombok 中的 data 注解。它的作用是自动为用户自定义的类添加生成的特殊方法例如 __init__() 和 __repr__()。
from dataclasses import dataclassdataclass
class InventoryItem:Class for keeping track of an item in inventory.name: strunit_price: floatquantity_on_hand: int 0def total_cost(self) - float:return self.unit_price * self.quantity_on_hand上面的类不需要单独再写下面的函数dataclass 装饰器会自动生成。
def __init__(self, name: str, unit_price: float, quantity_on_hand: int 0):self.name nameself.unit_price unit_priceself.quantity_on_hand quantity_on_hand所以 dataclass 可以帮助我们简化代码提升开发效率具体的用法可以参考官方文档。
总结
在 Python 中虽然不支持传统的函数重载但我们可以通过 functools.singledispatch 方法来实现类似的功能。同时需要注意一下只有第一个参数的不同类型会被重载后面参数的类型变化会被忽略。