python实现方法重载

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)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值