stypes.MethodType--->注册一个方法
class Person:
def __init__(self, name):
self.name = name
def eat(self):
print("eat......")
def sleep(self):
print('sleep....')
person = Person('alice')
import types
person.sleep=types.MethodType(sleep,person)
person.sleep()
实现一:
import inspect
import types
class MultiMethod:
def __init__(self,name):
self._methods={}
self.__name__=name
def register(self,meth):
sig=inspect.signature(meth)
types=[]
sig.parameters.items()
for name,parm in sig.parameters.items():
if name=='self':
continue
parm.annotation
if parm.annotation is inspect.Parameter.empty:
raise TypeError(f'参数 {name} 必须是有注解')
if not isinstance(parm.annotation,type):
raise TypeError(f'参数 {name} 的注解必须是type的子类')
print(parm.default,'---->parm.default')
#
if parm.default is not inspect.Parameter.empty:
self._methods[tuple(types)]=meth
types.append(parm.annotation)
self._methods[tuple(types)]=meth
def __call__(self, *args):
types=tuple(type(arg) for arg in args[1:])
meth=self._methods.get(types,None)
if meth:
return meth(*args)
else:
raise TypeError(f'无此方法: {meth}')
def __get__(self, instance, owner):
if instance is not None:
#给instance注册self属性
return types.MethodType(self,instance)
else:
return self
class MultiDict(dict):
def __setitem__(self, key, value):
if key in self: #第一次注册只是将方法照常注册进类中
'''如果key存在,必须为MultiMethod或者可以被调用'''
current_value=self[key]
if isinstance(current_value,MultiMethod):#只有方法重载时才会走这一步判断
current_value.register(value)
else:
mvalue=MultiMethod(key)
mvalue.register(current_value)
mvalue.register(value)
super(MultiDict, self).__setitem__(key,mvalue)
else:
super(MultiDict, self).__setitem__(key,value)
class MutipleMeta(type):
def __new__(cls, name,base,clsdict):
print(clsdict,'---->clsdict')
return type.__new__(cls,name,base,dict(clsdict))
@classmethod
def __prepare__(metacls, name, bases):
return MultiDict()
class Spam(metaclass=MutipleMeta):
def bar(self,x:int,y:int):
print('bar 1 :',x,y)
def bar(self,s:str,n:int=0):
print('bar 2 :',s,n)
Spam().bar(1,2)
有时间再进行注解
实现二:
import types
class Multimethod:
def __init__(self,func):
self._methods={}
self.__name__=func.__name__
self._default=func
def match(self,*types):
def register(func):
#func的默认值参数个数
ndefaults=len(func.__defaults__) if func.__defaults__ else 0
for n in range(ndefaults+1):
self._methods[types[:len(types)-n]]=func
return self
return register
def __call__(self, *args):
types=tuple(type(arg) for arg in args[1:])
meth=self._methods.get(types,None)
if meth:
return meth(*args)
return self._default(*args)
def __get__(self, instance, owner):
if instance is not None:
return types.MethodType(self,instance)
return self
class Spam:
@Multimethod
def bar(self,*args):
raise TypeError('没有bar这个方法')
@bar.match(int,int)
def bar(self,x,y):
print(x,y)
@bar.match(str,int)
def bar(self,s,n=0):
print(s,n)
Spam().bar(1,2)