Using metaclasses, I'm trying to create an instance method by simplifying an existing instance method. The problem is that partial does not work with the instance method. This is a simple example of what I'm trying to achieve:
from functools import partial class Aclass(object): def __init__(self, value): self._value = value def complex(self, a, b): return a + b + self._value class Atype(type): def __new__(cls, name, bases, attrs): return super(Atype, cls).__new__(cls, name, (Aclass, ) + bases, attrs) def __init__(cls, name, bases, attrs): setattr(cls, 'simple', partial(cls.complex, b=1)) class B(metaclass=Atype): pass b = B(10) print(b.complex(1, 2)) print(b.simple(1))
and output:
13 Traceback (most recent call last): File "metatest.py", line 22, in <module> print(b.simple(1)) TypeError: complex() takes exactly 3 non-keyword positional arguments (1 given)
I decided to use lambda change:
setattr(cls, 'simple', partial(cls.complex, b=1))
in
setattr(cls, 'simple', lambda self, x: cls.complex(self, x, b=1))
but it is ugly and has problems with additional parameters.
I could create this method in an __init__ instance, but I think it makes more sense and is more efficient for this in the __init__ class using metaclasses.
Any ideas how to do this correctly?