Thanks to Andreas Waldenburger, THC4k (http://stackoverflow.com/ questions/4247036/python-recursively-getattribute) and others for their tips. I was able to find solution:
class Null(object): def __repr__(self): return "<Null>" def __str__(self): return '' def __nonzero__(self): return False class ResultAttrFactory(type): _cache = {} @classmethod def prepare(cls, base, result): dict_ = ResultAttr.__dict__.copy() dict_.update({ '_ResultAttr__base': base, '_ResultAttr__result': result}) return ('ResultAttr', (base,), dict_) def __new__(cls, base, result): if (base, result) in cls._cache: type_ = cls._cache[(base, result)] else: type_ = super(ResultAttrFactory, cls).__new__( cls, *cls.prepare(base, result)) cls._cache[(base, result)] = type_ return type_ def __init__(cls, base, result): pass class ResultAttr: """Should be used only with ResultAttrFactory""" @staticmethod def __new__(cls, arg1, name): return cls.__base.__new__(cls, arg1) def __init__(self, arg1, name): self.__name = name super(self.__class__, self).__init__(arg1) def get_result_attr(self, name): if self.__result.is_denorm_attr(name): attr = getattr(self.__result, name, None) else: attr = getattr(self.__result, name) return attr def __getattr__(self, name): lookup_name = "%s__%s" % (self.__name, name) attr = self.get_result_attr(lookup_name) if type(attr).__name__ == 'ResultAttr': type_ = attr.__base elif attr is None: type_ = Null else: type_ = type(attr) result_attr = ResultAttrFactory( type_, self.__result)(attr, lookup_name) return result_attr class BaseResult(object): """ >>> class Result(BaseResult): ... def __init__(self, *args, **kwargs): ... self.x = 35 ... self.y = 5 ... self.y__a = 3 ... self.y__b = 'hello' ... self.y__c__x = [1, 2, 3] ... super(Result, self, *args, **kwargs) >>> r = Result() >>> r.x 35 >>> type(r.x) <type 'int'> >>> r.y 5 >>> type(r.y) # doctest:+ELLIPSIS <class '....ResultAttr'> >>> r.y.a 3 >>> r.y.b 'hello' >>> r.y.c # Is there any way to raise AtrributeError here? <Null> >>> r.y.d Traceback (most recent call last): AttributeError: 'Result' object has no attribute 'y__d' >>> r.y.c.x [1, 2, 3] """ def is_denorm_attr(self, name): return bool([k for k in self.__dict__.keys() if "%s__" % name in k]) def __getattribute__(self, name): attr = super(BaseResult, self).__getattribute__(name) if name in ('__dict__', 'is_denorm_attr'): return attr if self.is_denorm_attr(name): return ResultAttrFactory(type(attr), self)(attr, name) else: return attr if __name__ == '__main__': import doctest doctest.testmod() https://gist.github.com/710977 The only problem is: >>> r.y.c <Null> Is there any way to raise AtrributeError here? Also is there any negative side effects of such method? -- http://mail.python.org/mailman/listinfo/python-list