4

I'm trying to use inspect.getmembers() to list all the writeable attributes of a class. Is there a way to query if a class attribute is readonly or writeable?

Edit: I'm using the first solution from https://stackoverflow.com/a/3818861/2746401 and get an error when trying to copy read-only attributes (e.g. __doc__). I want to filter our these read-only properties and only copy the writeable ones

3
  • 1
    What are you going to do with that information? What does it mean to you to be read only or writable (are you talking about descriptors like @property? What about interference via __getattr[ibute]__/__setattr__?) Commented Mar 31, 2017 at 11:05
  • I'm using the first solution from stackoverflow.com/a/3818861/2746401 and get an error when read-only attributes (e.g. doc) are copied. I want to filer our these read-only properties and only copy the writeable ones. Commented Mar 31, 2017 at 11:49
  • Please edit to include the context in the question. Commented Mar 31, 2017 at 11:51

2 Answers 2

4

Most names will be settable by default. The exceptions are the data descriptor objects and classes that define the __setattr__ hook.

A data descriptor is any attribute of the class that has a __get__ method and at least either a __set__ or a __delete__ method. These methods are used when you try to set or delete the attribute on an instance of the class.

Data descriptors with a __set__ method may not be writeable, and it'll depend on the exact descriptor implementation what they'll allow. A property object is such a data descriptor; if the property has a fset attribute set to None it won't be writeable. If property().fset is not set to None but to a callable, then that callable determines if the attribute is writeable.

In addition, any data descriptor with only a __delete__ method can't be written either, the lack of a __set__ method results in a AttributeError when you try to set the attribute name on the instance.

A __setattr__ hook intercepts all attribute setting, and can prevent any such action to fail. There is a corresponding __delattr__ hook too, which matters if you want to count deleting attributes as writing.

In other words, this is really hard to determine, not in a generic way, once descriptors or a __setattr__ hook are involved.

Sign up to request clarification or add additional context in comments.

Comments

0

Here comes the necromancer.

If AttributeError is thrown on attempting to write to a read-only attribute, as should happen, you catch:

def isro(o,attr):

  v=getattr(o,attr);

  try:
    setattr(o,attr,v);
    return False;

  except AttributeError:
    return True;

^Here we attempt to write with the already existing value, assumed to be valid for attr. If it fails, it's read only. Else it's not.

A simplistic test, to which there might be edge cases. Feel free to point them out if you know them.

I do not think this check would be fast if done in bulk, however; haven't tested. But my gut says filter out the read-only attributes in such cases:

filtered=[
  attr for attr in attr_list
  if not isro(o,attr)
];

You run the check once per attribute, as opposed to per attribute for each object: should be the more performant approach is what my senses tell me. What remains then is walking through the filtered list of attributes.

Again, feel free to point out anything missing. This is just the quick-n-dirty I applied to solve this issue for myself.

Ta-ta.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.