I've been doing some research into this and there appear to be a few scenarios where you can do this, however no perfect solution:
- If you define instance variables using
@property
decorators, then it will show up when doing dir(class_type)
- Similarly, you can define the allowed list of instance attributes using
__slots__
magic var, and then just do class_type.__slots__
to get your instance vars.
- A bit more hacky, but you can read the source code of the class, and then look for any references to
self.varname = expression
. This of course assumes self
will is always how the class instance is referenced, and would fail in scenarios like inner classes or self
being reassigned to another varname. Also wouldn't pick up things like setattr(self, varname, expression)
, which you'd need other logic to detect.
- Probably more robust than option #3, you could use the
ast
module and use that to parse the class source code. Then do some searching to find expressions that might write attributes to the class self
.
Check out this example:
import dill, re
class Test:
__slots__ = ["x","y","z"]
def __init__(self):
self.x = 0
self.y = 1
self.z = 2
@property
def q(self):
return self.x
# this grabs those defined using __slots__ or @property
print(dir(Test))
# this looks at class source
# may need to play around with the regex more...
s = dill.source.getsource(Test)
var_finder = re.compile("self\.([^\W]+)\s*\=")
print(set(var_finder.findall(s)))
I personally think adding __slots__
on your class is the best approach. For sphinx documentation, which was my use case, that seems to be the best way to get autosummary
directive to pick up those instance variables.