As far as I know, dir
is the way to do it for an object at a current moment. From help(dir)
:
Help on built-in function dir in module builtins:
dir(...)
dir([object]) -> list of strings
If called without an argument, return the names in the current scope.
Else, return an alphabetized list of names comprising (some of) the attributes
of the given object, and of attributes reachable from it.
If the object supplies a method named __dir__, it will be used; otherwise
the default dir() logic is used and returns:
for a module object: the module's attributes.
for a class object: its attributes, and recursively the attributes
of its bases.
for any other object: its attributes, its class's attributes, and
recursively the attributes of its class's base classes.
I'm almost certain it's not possible to enumerate everything that could belong to an instance, given Python's dynamic nature. It lets you add attributes to an instance whenever you want.
To illustrate, consider the following code:
# This class has nothing but the built-in methods
class MyClass:
pass
mc = MyClass()
# so an instance of it has nothing but the built-in methods
print(dir(mc))
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
# But, we can dynamically add things to the class:
mc.newattr = 'bob'
# now, `newattr` has been added.
print(dir(mc))
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'newattr']
As you can see, standard Python classes don't have a limit on what can be seen in an instance. You add (and remove) attributes and methods willy-nilly, and dir
has no way to predict this.
If you were designing your own code, and wanted to stop this behavior, you can define the class variable __slots__
:
Here's a slightly modified version of that code:
class MyClass:
__slots__ = ['newattr']
mc = MyClass()
print(dir(mc))
mc.newattr = 'bob'
print(dir(mc))
mc.nextnew = 'sue'
# Traceback (most recent call last):
# File "/Users/bkane/tmp.py", line 12, in <module>
# mc.nextnew = 'sue'
# AttributeError: 'MyClass' object has no attribute 'nextnew'
But I wouldn't do that for code I wasn't designing from the ground up. Some libraries won't work if you remove their ability to dynamically modify instance structure.