python - Method overloading decorator -
i'm trying write decorator provides method overloading functionality python, similar 1 mentioned in pep 3124.
the decorator wrote works great regular functions, can't work methods in class.
here decorator:
class overload(object): def __init__(self, default): self.default_function = default self.type_map = {} self.pos = none def __call__(self, *args, **kwargs): print self try: if self.pos none: pos = kwargs.get("pos", 0) else: pos = self.pos print args, kwargs return self.type_map[type(args[pos])](*args, **kwargs) except keyerror: return self.default_function(*args, **kwargs) except indexerror: return self.default_function(*args, **kwargs) def overload(self, *d_type): def wrapper(f): dt in d_type: self.type_map[dt] = f return self return wrapper
when attempt implement this:
class myclass(object): def __init__(self): self.some_instance_var = 1 @overload def print_first_item(self, x): return x[0], self.some_instance_var @print_first_item.overload(str) def print_first_item(self, x): return x.split()[0], self.some_instance_var
i typeerror
when run it:
>>> m = myclass() >>> m.print_first_item(1) <__main__.overload object @ 0x2> (1,) {} traceback (most recent call last): file "<stdin>", line 1, in <module> file "overload.py", line 17, in __call__ return self.default_function(*args, **kwargs) typeerror: print_first_item() takes 2 arguments (1 given) >>>
my question is: how can access instance of myclass
(i.e. self
) within decorated method?
essentially, overload
class needs __get__
method:
def __get__(self, obj, cls): # called on access of myclass.print_first_item. # return wrapper calls our print "get", self, obj, cls if obj none: # function checks here, leave that. return self else: return lambda *a, **k: self(obj, *a, **k)
why?
well, use overload
object kind of function replacement. want it, function, represent in method context different signature.
short explanation how method access works:
object.meth(1, 2)
gets translated to
object.__dict__['meth'].__get__(object, type(object))(1, 2)
a function's __get__()
returns method object wraps function prepending object parameter list (where results in self
):
realmethod = object.__dict__['meth'].__get__(object, type(object)) realmethod(1, 2)
where realmethod
method object knows function called , self
given , calls "real" function appropriately transforming call into
meth(object, 1, 2)
.
this behaviour imitate in new __get__
method.
Comments
Post a Comment