Order in metaclass

Peter Otten __peter__ at web.de
Wed Oct 13 22:03:47 CEST 2004


Carlos Ribeiro wrote:

> Ok. Just as an exercise -- at this point we're far from safe Python
> land anyway, and it's not recommended to push it beyond this limit...
> ;-) Pseudo code only:
> 
> class Foo:
>     # loop that creates attributes out of a list
>     for name, val in list:
>         locals()[name] = val

Agreed.
 
> or (actual code tested):
> 
>>>> class Bar:
> ...         a,b,c,d = (1,2,3,4)
> ...
>>>> vars(Bar)
> {'a': 1, '__module__': '__main__', 'b': 2, 'd': 4, 'c': 3, '__doc__':
> {None}

You cannot rely on a vars() because it produces a dict - and dictionaries
don't preserve the insertion order by design. 

> The ordering became (a,b,d,c); and the code would have no way to tell
> that 'c' was supposed to be classified before 'd', because the
> getframe trick would return the same line.

No, it doesn't:

>>> class Bar:
...     a, b, c, d = "xyzt"
...     print sys._getframe().f_code.co_names
...
('__name__', '__module__', 'a', 'b', 'c', 'd', 'sys', '_getframe', 'f_code',
'co_names')

whereas

>>> vars(Bar).keys()
['a', '__module__', 'b', 'd', 'c', '__doc__']

Of course there are other ways to garble the co_names order:

>>> class Any:
...     def __getattr__(self, name): return name
...
>>> any = Any()
>>> class Bar:
...     x = any.d
...     a, b, c, d = "xyzt"
...     print sys._getframe().f_code.co_names
...
('__name__', '__module__', 'any', 'd', 'x', 'a', 'b', 'c', 'sys',
'_getframe', 'f_code', 'co_names')

All very useless/interesting stuff :-)

Peter




More information about the Python-list mailing list