[Python-Dev] Skiping searching throw dictionaries of mro() members. (original) (raw)

Sokolov Yura falcon at intercable.ru
Wed Sep 14 19:12:36 CEST 2005


Excuse my english. I have a complex Idea. It can be not worth, but just look at. It touches the classes and inheritance. Base point: We change classes not too often. But every look at a member leads to search throw a dict of all bases in ierarhy till member found. We could cache this search in class.dict itself and check only bases versions. Lets see: we have some classes: metaclass=object class a: ....def meth_a(self): ........pass class b: ....def meth_b(self): ........pass class c(a,b): ....pass Every class has mro.

c.mro() [<class '__main__.c'>, <class '__main__.a'>, <class '__main__.b'>, <type 'object'>] if we call methon from a base class, we look at c.dict and at dict of every inherited class till found the method itself. so c.meth_a() leads to search throw c.dict and a.dict c.meth_b() leads to search throw c.dict , a.dict and b.dict

We could cash looks by this way: Store with a class its version. Every time after creation when we change a class (add,remove or chage class member, including base, bases and mro) , we increase the version number. Lets call it VERSION Also store a tuple MRO_VERSION=tuple(base.VERSION for base in self.mro()). It changes, when we touches base, bases or self.mro) Store with every class member a tuple : MEMBER_VERSION=(<self.mro version>,) When we add member to (or change member of) class dict directly, we store in this tuple (MRO_VERSION,class.mro().index(class)).

When we search a class member: a) and have not found it in class.dict, we search it throw mro() by a classic way. If we've found it (in a class BASE), we store it in class.dict with a tuple MEMBER_VERSION=(MRO_VERSION, class.mro().index(BASE)). Also we check all of seen base.VERSION to match their cached in MRO_VERSION values. If some is not match, we should update MRO_VERSION (berfore storing founded member in a class.dict) and adjust VERSION. If it was not found, we could store a (MRO_VERSION, class.mro().index(class)) with an internal value NotFound or do not store anything, and report that we have not found anything (so we search in an object itself). b) When we've found a class member in class.dict we check versions if MEMBER_VERSION[0]==class.MRO_VERSION (the same object) then we just compare MRO_VERSION[i]==class.mro()[i].VERSION for i in range(MEMBER_VERSION[1]+1) and not search throw mro()[i].dict what we are doing now. If all versions concur, we return found member (or, if we've found previously stored NotFound, we report that we have not found anything) if version of MRO_VERSION[j]!=class.mro()[j].VERSION and class!=class.mro()[j] (here can be a bug, one must think about it more) then we revert to a) point, but search throw [base.dict for base in class.mro()[j:]], (and, of cause, update MRO_VERSION) if MEMBER_VERSION[0]!=class.MRO_VERSION, we reverts to a) point.

That's all. PS. We can subclass module from a builtin, so we leave one dict lookup.



More information about the Python-Dev mailing list