Example situation:
So, lets assume I'm creating some inspection tool, and I wanna have a methods for listing callable fields, which are some methods, for listing data fields (normal attributes) and properties (so I can also add information on which descriptor methods are declared, to see if attribute is constant, etc).
Questions:
- How do I iterate over some objects fields?
- How do I recognise whether some field is property? (Checking whether it is callable is easy, with
callable
builtin function, just trying to call some object, or checking whether it has__call__
attribute; those ways of checking are listed from most to least reliable and safe)
Known approaches:
Ad. 1
Easiest way I can think of is using dir()
or checking __slots__
. Still, I know that dir()
is intended to be used in REPL mode only, but I dont know why, so here's some bonus question: "Why shouldn't I use dir()
in real-life usage? Or should I?".
Also, I think I remember something about __dict__
, but I'd have to consult Data model to be sure how to use it, and if it would do what I need. Anyway, I'd also have to consult that article when trying to use __slots__
.
Ad. 2
No freaking idea. I tried using plain getattr(obj, name)
, object.__getattribute__(obj, name)
, obj.__getattribute__(name)
, obj.__getattr__(name)
(for some cases only) to get descriptor object (one that implements __get__
, __set__
, etc) and check for those methods, but instead, obj.name.__get__(...)
is called.
Post Scriptum
This isn't real-life example, more like my way of figuring out nuances of python. If there is some reason why I shouldn't even try to do it, I'll be glad to hear it, but I will also like to know how to do it, if I REALLY (like "I know that is bad, but if I won't do it, my boss will fire me"-really) need to.
I'm mostly interested in p3.3+, but those question stand for p2.7.x too.
== EDIT ==
Ad. 2
With help from user2357112 I got this:
>>> class A:
... @property
... def x(self):
... return 1
...
>>> a = A()
>>> a.x
1
>>> isinstance(a.x, int)
True
>>> isinstance(a.x, property)
False
>>> isinstance(type(a).x, property)
True