-- TOC --
前面有文章详细解释@singledispatch装饰器,也有文章详细解释用于类方法的@classmethod和@staticmethod,本文补充另一个用于类方法重载的装饰器:@singledispatchmethod。
从Python3.8开始提供@singledispatchmethod。
@singledispatch可以重载函数接口的第1个参数,@singledispatchmethod同样是重载第1个参数,确切地说,是重载第1个非cls或self参数。
代码祭天:
from functools import singledispatchmethod
class clock():
def __new__(cls):
raise NotImplementedError('please use classmethod to instantiation')
@staticmethod
def init(self, hour, minute, second):
self.hour = hour
self.minute = minute
self.second = second
@singledispatchmethod
@classmethod
def create(cls, hour, minute, second):
print('int create')
if not (0 < hour < 23
and 0 < minute < 60
and 0 < second < 60):
return
obj = object.__new__(cls)
clock.init(obj, hour, minute, second)
return obj
@create.register(str)
@classmethod
def _(cls, hour, minute, second):
print('str create')
if not (0 < int(hour) < 23
and 0 < int(minute) < 60
and 0 < int(second) < 60):
return
obj = object.__new__(cls)
clock.init(obj, int(hour), int(minute), int(second))
return obj
@create.register(tuple)
@classmethod
def _(cls, tt):
print('tuple create')
if not (0 < tt[0] < 23
and 0 < tt[1] < 60
and 0 < tt[2] < 60):
return
obj = object.__new__(cls)
clock.init(obj, tt[0], tt[1], tt[2])
return obj
@singledispatchmethod
def show(self, tag):
print('str-->'+tag, str(self.hour)+':'
+str(self.minute)+':'
+str(self.second))
@show.register(int)
def _(self, tag):
print('int-->'+str(tag), str(self.hour)+':'
+str(self.minute)+':'
+str(self.second))
c1 = clock.create(1,2,3)
c1.show('beijing')
c2 = clock.create('3',4,5)
c2.show(24)
c3 = clock.create((5,6,6))
c3.show('a')
try:
c4 = clock()
except Exception as e:
print(repr(e))
这段测试代码,将@classmethod,@staticmethod,以及本文的重点@singledispatchmethod都用上了。而且没有定义__init__
,并且在__new__
内直接raise,需仔细品味。
这样设计,实际上是不允许通过class名称这种常规的方式来创建对象,强迫代码使用者使用create这个被@singledispatchmetho修饰过的classmethod来创建对象。
运行结果符合预期:
$ python3 sdm.py
int create
str-->beijing 1:2:3
str create
int-->24 3:4:5
tuple create
str-->a 5:6:6
NotImplementedError('please use classmethod to instantiation')
有了@singledispatchmethod,再配合上@classmethod,我们就可以重载class的factory method,提升代码的可读性和优雅值!
本文链接:https://cs.pynote.net/sf/python/202209091/
-- EOF --
-- MORE --