AME
AME

Reputation: 2609

check if something is an attribute or decorator in python

I want to wrap a model class of a legacy codebase. The model class has a dictionary with meta-information and properties that access that dictionary as well as attributes. I want to unify the access to meta information, properties, and attributes with the an_object[some_key] syntax using __getitem__. The problem is, that some of the properties have getters but not setters. So trying to check if an attribute exists (via hasattr) returns True, but then setting that attribute fails because there is no property defined.

How can I decide if I can set an attribute safely or if it is an property that I need to set in the meta-dictionary?

Upvotes: 0

Views: 1487

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1123420

You can detect if something is a property, by looking at the same attribute on the class:

class_attribute = getattr(type(instance), some_key, None)
if isinstance(class_attribute, property):
    # this is a property
    if class_attribute.fset is None:
        print "Read-only"

You can also test .fget and .fdel to test if the property has a getter and a deleter, respectively.

However, you can always catch the AttributeError exception to deal with the setter missing:

>>> class Foo(object):
...     @property
...     def bar(self):
...         return 'spam'
... 
>>> f = Foo()
>>> class_attribute = getattr(type(f), 'bar', None)
>>> isinstance(class_attribute, property)
True
>>> class_attribute.fget
<function bar at 0x10aa8c668>
>>> class_attribute.fset is None
True
>>> try:
...     f.bar = 'baz'
... except AttributeError:
...     print 'Read-only'
... 
Read-only

Upvotes: 4

Related Questions