[Tutor] class variables

eryksun eryksun at gmail.com
Sat Dec 21 20:31:47 CET 2013


On Sat, Dec 21, 2013 at 12:40 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Sat, Dec 21, 2013 at 08:41:17AM -0500, eryksun wrote:
>>
>>     >>> vars(type)['__base__']
>>     <member '__base__' of 'type' objects>
>
> Oooh, nice! I always forget about vars(), and end up messing about with
> __dict__.

It's a bit more efficient to use the __dict__ attribute, but I like
built-in vars().

vars(obj) is basically doing the equivalent of getattr(obj,
'__dict__'), so there's that plus the overhead of the call. vars has
to play it safe. A class may define a custom __dict__ property, such
as the tuple subclass created by namedtuple:

    from collections import namedtuple

    Point = namedtuple('Point', 'x y')
    p = Point(1, 2)

    >>> type(vars(Point)['__dict__'])
    <class 'property'>

    >>> vars(p)
    OrderedDict([('x', 1), ('y', 2)])

Even if an object has a dict, it would be wrong for vars to naively
return a reference. A class might be overriding __getattribute__ to
create dynamic attributes or raise an AttributeError for '__dict__'.
Also, bypassing the descriptor would bypass the proxy protecting a
class dict, enabling silliness:

    from ctypes import pythonapi, py_object

    # 3.3+
    pythonapi.PyObject_GenericGetDict.restype = py_object
    pythonapi.PyObject_GenericGetDict.argtypes = [py_object]

    str_dict = pythonapi.PyObject_GenericGetDict(str)
    str_dict['lower'] = str_dict['upper']

    >>> 'abc'.lower()
    'ABC'


More information about the Tutor mailing list