Using metaclasses, I am trying to create an instance method by simplifying an existing instance method. The problem is that partial does not work with instance method. This is a simple example of what I try 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 the output is:
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 have solved using lambda changing:
setattr(cls, 'simple', partial(cls.complex, b=1))
to:
setattr(cls, 'simple', lambda self, x: cls.complex(self, x, b=1))
but it is ugly and has problems with optional parameters.
I could create these method at the instance __init__
but I guess it makes more sense, and is more efficient to do it on class __init__
using metaclasses.
Any ideas how to do it properly?