How to get a complete list of object's methods and attributes?
Question:
dir(re.compile(pattern))
does not return pattern as one of the lists’s elements. Namely it returns:
['__copy__', '__deepcopy__', 'findall', 'finditer', 'match', 'scanner', 'search', 'split', 'sub', 'subn']
According to the manual, it is supposed to contain
the object’s attributes’ names, the
names of its class’s attributes, and
recursively of the attributes of its
class’s base classes.
It says also that
The list is not necessarily complete.
Is there a way to get the complete list? I always assumed that dir returns a complete list but apparently it does not…
Also: is there a way to list only attributes? Or only methods?
Edit: this is actually a bug in python -> supposedly it is fixed in the 3.0 branch (and perhaps also in 2.6)
Answers:
For the complete list of attributes, the short answer is: no. The problem is that the attributes are actually defined as the arguments accepted by the getattr
built-in function. As the user can reimplement __getattr__
, suddenly allowing any kind of attribute, there is no possible generic way to generate that list. The dir
function returns the keys in the __dict__
attribute, i.e. all the attributes accessible if the __getattr__
method is not reimplemented.
For the second question, it does not really make sense. Actually, methods are callable attributes, nothing more. You could though filter callable attributes, and, using the inspect
module determine the class methods, methods or functions.
That is why the new __dir__()
method has been added in python 2.6
see:
- http://docs.python.org/whatsnew/2.6.html#other-language-changes (scroll down a little bit)
- http://bugs.python.org/issue1591665
Here is a practical addition to the answers of PierreBdR and Moe:
- For Python >= 2.6 and new-style classes,
dir()
seems to be enough.
-
For old-style classes, we can at least do what a standard module does to support tab completion: in addition to dir()
, look for __class__
, and then to go for its __bases__
:
# code borrowed from the rlcompleter module
# tested under Python 2.6 ( sys.version = '2.6.5 (r265:79063, Apr 16 2010, 13:09:56) n[GCC 4.4.3]' )
# or: from rlcompleter import get_class_members
def get_class_members(klass):
ret = dir(klass)
if hasattr(klass,'__bases__'):
for base in klass.__bases__:
ret = ret + get_class_members(base)
return ret
def uniq( seq ):
""" the 'set()' way ( use dict when there's no set ) """
return list(set(seq))
def get_object_attrs( obj ):
# code borrowed from the rlcompleter module ( see the code for Completer::attr_matches() )
ret = dir( obj )
## if "__builtins__" in ret:
## ret.remove("__builtins__")
if hasattr( obj, '__class__'):
ret.append('__class__')
ret.extend( get_class_members(obj.__class__) )
ret = uniq( ret )
return ret
(Test code and output are deleted for brevity, but basically for new-style objects we seem to have the same results for get_object_attrs()
as for dir()
, and for old-style classes the main addition to the dir()
output seem to be the __class__
attribute.)
This is how I do it, useful for simple custom objects to which you keep adding attributes:
Given an object created with obj = type("Obj",(object,),{})
, or by simply:
class Obj: pass
obj = Obj()
Add some attributes:
obj.name = 'gary'
obj.age = 32
then, to obtain a dictionary with only the custom attributes:
{key: value for key, value in obj.__dict__.items() if not key.startswith("__")}
# {'name': 'gary', 'age': 32}
Only to supplement:
dir()
is the most powerful/fundamental tool. (Most recommended)
-
Solutions other than dir()
merely provide their way of dealing the output of dir()
.
Listing 2nd level attributes or not, it is important to do the sifting by yourself, because sometimes you may want to sift out internal vars with leading underscores __
, but sometimes you may well need the __doc__
doc-string.
__dir__()
and dir()
returns identical content.
__dict__
and dir()
are different. __dict__
returns incomplete content.
-
IMPORTANT: __dir__()
can be sometimes overwritten with a function, value or type, by the author for whatever purpose.
Here is an example:
\...\torchfun.py in traverse(self, mod, search_attributes)
445 if prefix in traversed_mod_names:
446 continue
447 names = dir(m)
448 for name in names:
449 obj = getattr(m,name)
TypeError: descriptor __dir__
of 'object'
object needs an argument
The author of PyTorch modified the __dir__()
method to something that requires an argument. This modification makes dir()
fail.
-
If you want a reliable scheme to traverse all attributes of an object, do remember that every pythonic standard can be overridden and may not hold, and every convention may be unreliable.
dir(re.compile(pattern))
does not return pattern as one of the lists’s elements. Namely it returns:
['__copy__', '__deepcopy__', 'findall', 'finditer', 'match', 'scanner', 'search', 'split', 'sub', 'subn']
According to the manual, it is supposed to contain
the object’s attributes’ names, the
names of its class’s attributes, and
recursively of the attributes of its
class’s base classes.
It says also that
The list is not necessarily complete.
Is there a way to get the complete list? I always assumed that dir returns a complete list but apparently it does not…
Also: is there a way to list only attributes? Or only methods?
Edit: this is actually a bug in python -> supposedly it is fixed in the 3.0 branch (and perhaps also in 2.6)
For the complete list of attributes, the short answer is: no. The problem is that the attributes are actually defined as the arguments accepted by the getattr
built-in function. As the user can reimplement __getattr__
, suddenly allowing any kind of attribute, there is no possible generic way to generate that list. The dir
function returns the keys in the __dict__
attribute, i.e. all the attributes accessible if the __getattr__
method is not reimplemented.
For the second question, it does not really make sense. Actually, methods are callable attributes, nothing more. You could though filter callable attributes, and, using the inspect
module determine the class methods, methods or functions.
That is why the new __dir__()
method has been added in python 2.6
see:
- http://docs.python.org/whatsnew/2.6.html#other-language-changes (scroll down a little bit)
- http://bugs.python.org/issue1591665
Here is a practical addition to the answers of PierreBdR and Moe:
- For Python >= 2.6 and new-style classes,
dir()
seems to be enough. -
For old-style classes, we can at least do what a standard module does to support tab completion: in addition to
dir()
, look for__class__
, and then to go for its__bases__
:# code borrowed from the rlcompleter module # tested under Python 2.6 ( sys.version = '2.6.5 (r265:79063, Apr 16 2010, 13:09:56) n[GCC 4.4.3]' ) # or: from rlcompleter import get_class_members def get_class_members(klass): ret = dir(klass) if hasattr(klass,'__bases__'): for base in klass.__bases__: ret = ret + get_class_members(base) return ret def uniq( seq ): """ the 'set()' way ( use dict when there's no set ) """ return list(set(seq)) def get_object_attrs( obj ): # code borrowed from the rlcompleter module ( see the code for Completer::attr_matches() ) ret = dir( obj ) ## if "__builtins__" in ret: ## ret.remove("__builtins__") if hasattr( obj, '__class__'): ret.append('__class__') ret.extend( get_class_members(obj.__class__) ) ret = uniq( ret ) return ret
(Test code and output are deleted for brevity, but basically for new-style objects we seem to have the same results for get_object_attrs()
as for dir()
, and for old-style classes the main addition to the dir()
output seem to be the __class__
attribute.)
This is how I do it, useful for simple custom objects to which you keep adding attributes:
Given an object created with obj = type("Obj",(object,),{})
, or by simply:
class Obj: pass
obj = Obj()
Add some attributes:
obj.name = 'gary'
obj.age = 32
then, to obtain a dictionary with only the custom attributes:
{key: value for key, value in obj.__dict__.items() if not key.startswith("__")}
# {'name': 'gary', 'age': 32}
Only to supplement:
dir()
is the most powerful/fundamental tool. (Most recommended)-
Solutions other than
dir()
merely provide their way of dealing the output ofdir()
.Listing 2nd level attributes or not, it is important to do the sifting by yourself, because sometimes you may want to sift out internal vars with leading underscores
__
, but sometimes you may well need the__doc__
doc-string. __dir__()
anddir()
returns identical content.__dict__
anddir()
are different.__dict__
returns incomplete content.-
IMPORTANT:
__dir__()
can be sometimes overwritten with a function, value or type, by the author for whatever purpose.Here is an example:
\...\torchfun.py in traverse(self, mod, search_attributes) 445 if prefix in traversed_mod_names: 446 continue 447 names = dir(m) 448 for name in names: 449 obj = getattr(m,name)
TypeError: descriptor
__dir__
of'object'
object needs an argumentThe author of PyTorch modified the
__dir__()
method to something that requires an argument. This modification makesdir()
fail. -
If you want a reliable scheme to traverse all attributes of an object, do remember that every pythonic standard can be overridden and may not hold, and every convention may be unreliable.