1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| class OverMethod:
def __init__(self, func):
#print("\nover init:", func.__name__, func)
if not callable(func) and not hasattr(func, "__get__"):
raise TypeError(f"{func!r} n'est pas une méthode")
self.funcs = {}
self.funcs["_"] = func
def register(self, cls, method=None):
""" nouvelle méthode avec signature différente """
ann = getattr(cls, '__annotations__', {})
if not ann:
raise Exception("Types doivent être présents !")
#print("Signature de la méthode:", ann.values())
name = f"{'_'.join(a for a in ann.values())}"
self.funcs[name] = cls
#print("self.funcs:", self.funcs)
return method
def __get__(self, obj, cls=None):
""" recherche méthode avec bonne signature """
def _method(*args, **kwargs):
name = f"{'_'.join(type(a).__name__ for a in args)}"
# gérer kwargs trop compliqué ...
if name in self.funcs:
if f := self.funcs[name]:
return f(obj, *args, **kwargs)
else:
raise Exception("?")
else:
#print(f"# ({name}) n'existe pas pour {self.func.__name__}")
return self.funcs["_"](obj, *args, **kwargs)
return _method
class A:
@OverMethod
def __init__(self):
print("\n#init defaut")
self.name = "un test..."
@__init__.register
def _(self, name: str):
print("\n#init custum")
self.name = name
@OverMethod
def print(self, name: str, message='+'):
print(f"{'defaut str':14} : {self.name} : {name} {message}")
@print.register
def _(self, name: int, message: str = '+'):
print(f"{'int, str':14} : {self.name} : {name} {message}")
@print.register
def _(self, name: str, message: str = "+"):
print(f"{'str, str':14} : {self.name} : {name} : {message}")
@print.register
def _(self, x: int):
print(f"{'int':14} : {self.name} : {x}")
a = A()
a.print("un", "deux")
a.print(name=1, message="deux") #FIXME gere pas kwargs
a.print(1, "deux")
a.print(100)
a.print("un")
a.print([]) # si pas signature, prend @OverMethod
b = A("autre")
b.print([])
try:
c = A("autre", 8, 8, 9)
except TypeError:
print("Exception trop de paramètres") |
Partager