Metaclass conundrum - binding value from an outer scope

Peter Otten __peter__ at web.de
Sat Apr 22 17:14:54 EDT 2017


Skip Montanaro wrote:

>> 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

In Python 3 you should see the correct signature, for Python 2 I think this 
addressed by Michele Simionato's

https://pypi.python.org/pypi/decorator
http://pythonhosted.org/decorator/documentation.html#id8

module.



More information about the Python-list mailing list