出于性能原因,Python始终在类(和父类的类)中
__dict__查找魔术方法,并且不使用常规的属性查找机制。一种解决方法是在类创建时使用元类为魔术方法自动添加代理。例如,我使用这种技术来避免必须为包装器类编写样板调用方法。
class Wrapper(object): """Wrapper class that provides proxy access to an instance of some internal instance.""" __wraps__ = None __ignore__ = "class mro new init setattr getattr getattribute" def __init__(self, obj): if self.__wraps__ is None: raise TypeError("base class Wrapper may not be instantiated") elif isinstance(obj, self.__wraps__): self._obj = obj else: raise ValueError("wrapped object must be of %s" % self.__wraps__) # provide proxy access to regular attributes of wrapped object def __getattr__(self, name): return getattr(self._obj, name) # create proxies for wrapped object's double-underscore attributes class __metaclass__(type): def __init__(cls, name, bases, dct): def make_proxy(name): def proxy(self, *args): return getattr(self._obj, name) return proxy type.__init__(cls, name, bases, dct) if cls.__wraps__: ignore = set("__%s__" % n for n in cls.__ignore__.split()) for name in dir(cls.__wraps__): if name.startswith("__"): if name not in ignore and name not in dct: setattr(cls, name, property(make_proxy(name)))用法:
class DictWrapper(Wrapper): __wraps__ = dictwrapped_dict = DictWrapper(dict(a=1, b=2, c=3))# make sure it worked....assert "b" in wrapped_dict # __contains__assert wrapped_dict == dict(a=1, b=2, c=3) # __eq__assert "'a': 1" in str(wrapped_dict) # __str__assert wrapped_dict.__doc__.startswith("dict()") # __doc__


