Why property works only for objects?

Michal Kwiatkowski ruby at no.spam
Sat Mar 11 22:29:40 CET 2006


Alex Martelli napisał(a):
>>>> obj.__dict__
> {}
> 
> ...the presence of '__dict__' as an entry in C is confusing the issue,
> because that's what you get in this case as obj.__dict__.

It still bugs me. What's the actual procedure when doing attribute
assignment? I understand it like this:

obj.attr = value
 * if instance class has __setattr__, call it
   * else: if class has an attribute with name "attr" check if it's a
     descriptor; when it's overriding descriptor, call its __set__
     method, otherwise raise AttributeError
     * else: bind "attr" as object attribute

I've initialized C.__dict__ as plain dictionary, so it's not a
descriptor. C also doesn't have __setattr__ method. I'm probably wrong,
as __dict__ is considered somewhat special, but I can't really
understand to which degree. Any other attribute I try to bind to object
will be stored inside object dictionary, without looking up class
dictionary. __dict__ is special, because it's *the* dictionary that
stores all references to object's attributes. So, when assigning to
__dict__ I would expect old dictionary to be simply replaced with this
one. I don't understand why class attributes has any factor in this.

> C.__dict__ gives you a dictproxy, not a real dict, by the way:
> 
>>>> obj.__dict__ is C.__dict__['__dict__']
> True

Why is that? I've initialized it as dictionary. When the type was
changed and why? Is this used anywhere?

> The funny thing is that builtins like var, which should know better,
> also get fooled...:
> 
>>>> vars(obj)
> {}
>>>> vars(obj) is C.__dict__['__dict__']
> True

Docstring for vars says:
    With an argument, equivalent to object.__dict__.

So this behavior simply conforms to the doc.

> I think a fair case can be made that you've found a bug in Python here:
> the existence of that __dict__ in C's class body is clearly causing
> unintended anomalies.  Fortunately, getattr and friends don't in fact
> get confused, but vars does, as does assignment to obj.__dict__...

What solution do you propose?

mk
-- 
 . o .       >>  http://joker.linuxstuff.pl  <<
 . . o   It's easier to get forgiveness for being wrong
 o o o   than forgiveness for being right.



More information about the Python-list mailing list