0

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?

4

1 回答 1

3

您可以通过查看类上的相同属性来检测某物是否是属性:

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"

您还可以分别测试.fget.fdel测试属性是否具有 getter 和 deleter。

但是,您始终可以捕获AttributeError异常来处理缺少的 setter:

>>> 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
于 2013-04-23T13:20:34.437 回答