Skip to content Skip to sidebar Skip to footer

Unexpected Name Lookup On Properties

Consider this code: class Foo(object): @property def func(self): self.__dict__['func'] = 1 return 2 f = Foo() print f.func print f.func It prints 2 2. Wh

Solution 1:

Because f.func where f is an instance of Foo and func is a property descriptor triggers

Foo.func.__get__(f)

(see Descriptor protocol).

self.__dict__['func'] = 1 modifies the underlying dictionary of the f instance. It doesn't change the func attribute of the Foo class.

Foo.func takes precedence over f.func (= 1, newly created instance variable) because

If an instance’s dictionary has an entry with the same name as a data descriptor, the data descriptor takes precedence.

(copied from the link above).


You'll have to assign something to Foo.func if you want to replace the property:

classFoo(object):
    @propertydeffunc(self):
        Foo.func = 1return2

f = Foo()
print(f.func) # 2print(f.func) # 1

Solution 2:

According to this post, the attribute lookup process goes in this order:

  1. If attrname is a special (i.e. Python-provided) attribute for objectname, return it.
  2. Check objectname.__class__.__dict__ for attrname. If it exists and is a data-descriptor, return the descriptor result. Search all bases of objectname.__class__ for the same case.
  3. Check objectname.__dict__ for attrname, and return if found. If objectname is a class, search its bases too. If it is a class and a descriptor exists in it or its bases, return the descriptor result.
  4. Check objectname.__class__.__dict__ for attrname. If it exists and is a non-data descriptor, return the descriptor result. If it exists, and is not a descriptor, just return it. If it exists and is a data descriptor, we shouldn't be here because we would have returned at point 2. Search all bases of objectname.__class__ for same case.
  5. Raise AttributeError.

The property decorator adds a key-value pair to the object's class' __dict__, so it gets found in step 2. Names added to the object's __dict__ are checked in step 3. So between the two, properties take precedence.

Post a Comment for "Unexpected Name Lookup On Properties"