Metaclass conundrum - binding value from an outer scope
Skip Montanaro
skip.montanaro at gmail.com
Sat Apr 22 16:16:34 EDT 2017
> Another round, this time with a metaclass. As you have found partial() does
> not work as a method because it's not a descriptor (i. e. no __get__()
> method). Instead you can try a closure:
>
> def make_method(a):
> underlying = getattr(SomeOtherClass, a)
> @functools.wraps(underlying)
> def _meth(self, *args, **kw):
> return underlying(self._instance, *args, **kw)
> return _meth
>
> class SomeMeta(type):
> def __new__(cls, name, parents, dct):
> for a in dir(SomeOtherClass):
> if a[0] == "_": continue
> dct[a] = make_method(a)
> return super(SomeMeta, cls).__new__(cls, name, parents, dct)
Dang, Peter... That looks like it will do exactly what I need. Here's
help on SomeOtherClass with its one method:
class SomeOtherClass(__builtin__.object)
| Methods defined here:
|
| meth1(self)
| meth1 doc
...
And, here's SomeClass (__metaclass__ = SomeMeta), which defines meth2,
but steals meth1 from SomeOtherClass:
class SomeClass(__builtin__.object)
| Methods defined here:
|
| meth1(self, *args, **kw)
| meth1 doc
|
| meth2(self)
| meth2 doc
...
With a bit of introspection in make_method (or an extension of
functools.wraps), I can probably make SomeClass.meth1 have the same
signature as SomeOtherClass.meth1.
Thx,
Skip
More information about the Python-list
mailing list