Metaclass conundrum - binding value from an outer scope

Peter Otten __peter__ at web.de
Fri Apr 21 09:21:37 EDT 2017


Skip Montanaro wrote:

> On Thu, Apr 20, 2017 at 3:19 PM, Peter Otten <__peter__ at web.de> wrote:
> 
>> If being helpful really is the only purpose of the metaclass you can
>> implement a SomeClass.__dir__() method instead:
>>
>>      def __dir__(self):
>>          names = dir(self._instance)
>>          # <snip whatever post-processing you want>
>>          return names
>>
> 
> Thanks. That would probably get me halfway home in Python 3, but appears
> to have no effect in Python 2. It wouldn't solve the missing attributes in
> help()/pydoc either.

OK, looks like I messed up. 

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)





More information about the Python-list mailing list