[Python-Dev] Skiping searching throw dictionaries of mro() members.
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.
We change classes not too often. But every look at a member leads to
a __dict__ of all bases in ierarhy till member found. We could cache
this search in class.__dict__ itself and check only bases versions.
we have some classes:
Every class has mro.
[<class '__main__.c'>, <class '__main__.a'>, <class '__main__.b'>, <type
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
(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>,<number in mro>)
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:
and have not found it in class.__dict__, we search it throw mro() by a
If we've found it (in a class _BASE_), we store it in class.__dict__
with a tuple
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).
When we've found a class member in class.__dict__ we check versions
if MEMBER_VERSION==class.MRO_VERSION (the same object)
then we just compare MRO_VERSION[i]==class.mro()[i].VERSION for i
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!=class.MRO_VERSION, we reverts to a) point.
PS. We can subclass module from a __builtin__, so we leave one dict lookup.
More information about the Python-Dev