For various reasons, I have a class which delegates much functionality to a singleton instance of another class (exposed by pybind11) instead of inheriting from that class. So, the construction looks like this (this is in Python 2.7):
from someothermodule import SomeOtherClass as _SomeOtherClass class SomeClass(object): _instance = None def __init__(self): if self.__class__._instance is None: self._instance = _SomeOtherClass.instance() def __getattr__(self, key): return getattr(self._instance, key) ... and so on ... If someone tries help(SomeClass) or dir(SomeClass) today, none of the attributes or docstrings defined in SomeOtherClass are shown. It was almost a straightforward exercise to write a metaclass which defines methods on SomeClass which delegate to the underlying method on SomeOtherClass. My problem is evaluating the return value of getattr(SomeOtherClass, attr) immediately. The code in __new__ looks like this (somewhat abbreviated, but only lightly): class SomeMeta(type): def __new__(cls, name, parents, dct): for a in dir(SomeOtherClass): if a[0] == "_": continue underlying = getattr(SomeOtherClass, a) def _meth(self, *args): return underlying(self._instance, *args) _meth.__doc__ = underlying.__doc__ dct[a] = _meth return super(SomeMeta, cls).__new__(cls, name, parents, dct) (Hopefully the indentation is correct. I have no Emacs on this stupid Windows machine, so had to actually count my spaces.) Suppose SomeOtherClass has methods m1, m2, and m3, processed in that order coming out of the dir() call. All calls to SomeClass.m1, SomeClass.m2 and SomeClass.m3 will wind up calling SomeOtherClass.m3, because the variable "underlying" is evaluated late. I need it to be evaluated early (at the time _meth is defined), when it has the value corresponding to attributes "m1", "m2", or "m3". Thinking about it for a minute or two, I thought functools.partial() might save my bacon, but that only partially applies arguments. It won't work to bind the function name. I thought I might be able to use it like this: def _meth(self, underlying=None, *args): return underlying(...) then assign a partial function object to the dictionary: dct[a] = functools.partial(_meth, underlying=underlying) but that didn't seem to work (e.g., calling m1(1000) complained that int objects have no _instance attribute, so clearly self was not getting set properly), and it changes the runtime interface of the method (so it would look different to people using SomeClass). Maybe I need to construct the actual function assigned to dct[a] using types.FunctionType? There's bound to be a way to do this, and I'm almost certainly going to :dopeslap: myself when it's revealed, but I'm stuck on this. Any ideas? Thx, Skip -- https://mail.python.org/mailman/listinfo/python-list