-3

I was trying to dive in python and evaluating some of the builtin functions. The dir function returns a string list containing the names of all attributes of the given module. Because of that if I run the following code segment, I get an empty list:

import string
[x for x in dir(string) if callable(x) ]

Is There other functions or other ways, that I can combine with dir(string) for getting a list of Objects instead of row strings?

my goal is to do something like:

import string
[ x for x in ***(dir(string)) if callable(x) ]

and not something like the example in dive in python book

 methodList = [method for method in dir(object) if callable(getattr(object, method))]
Mauri
  • 1,185
  • 1
  • 13
  • 21

2 Answers2

3

That's because dir() returns a list of strings:

>>> import string
>>> dir(string)
['Formatter', 'Template', '_ChainMap', '_TemplateMetaclass', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_re', '_string', 'ascii_letters', 'ascii_lowercase', 'ascii_uppercase', 'capwords', 'digits', 'hexdigits', 'octdigits', 'printable', 'punctuation', 'whitespace']

String values are not callable; these are not the actual attribute values, they are the names.

If you wanted to to test those names as attributes on the string module, you'd have to use getattr(), or use the vars() function to get the strings namespace as a dictionary:

>>> getattr(string, 'Formatter')
<class 'string.Formatter'>
>>> callable(getattr(string, 'Formatter'))
True
>>> [name for name in dir(string) if callable(getattr(string, name))]
['Formatter', 'Template', '_ChainMap', '_TemplateMetaclass', 'capwords']
>>> [name for name, obj in vars(string).items() if callable(obj)]
['capwords', '_ChainMap', '_TemplateMetaclass', 'Template', 'Formatter']

The order differs here because dictionaries are unordered and dir() always sorts the return value. For modules, dir(module) simply returns sorted(vars(module)).

If you wanted the callable objects themselves and not the names, just filter the values of the vars() dictionary:

[obj for obj in vars(string).values() if callable(obj)]
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • I didn't link it here, no, but I did consider linking it. My apologies, I did think you had read it. Again, comments are ephemeral. Had you been critical of my post I would not have touched the comments (at most I'd have asked another mod to look at them). I'll ask another to take a look if they feel I was too quick to clean up here. Thing is, if I *don't* clean up the comments below my own posts when I see them as obsolete, then it can take a long time before they *are*. I'm just tidying up after myself here. – Martijn Pieters Sep 25 '17 at 11:13
  • Thanks, sounds all reasonable. No need for another mod to take a look. I think it was mostly the timinig that bothered me. – Sven Marnach Sep 25 '17 at 11:15
  • I updated the question, it was bad formulate. Have you an Idea? – Mauri Sep 25 '17 at 18:43
  • @MohamedEl: there you go. – Martijn Pieters Sep 25 '17 at 18:47
-1

callable(x) checks is x is an object that has a __call__() method. In your case, it doesn't, that's why the comprehension is returning an empty list

blue_note
  • 27,712
  • 9
  • 72
  • 90