14
\$\begingroup\$

In Python, you can use the dir function on any object to get a list of the names of its instance functions:

>>> dir('abc')
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__','__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

I'm wondering if this could be a useful golfing technique in a program than calls several lengthily named functions. In such a case, I could create a function selection function F:

F=lambda o,i:eval('o.'+dir(o)[i])

Now suppose I have a string s and I want store the result of capitalizing its first letter in the variable c. Then instead of c=s.capitalize(), I could note that capitalize is at position 33 in the above list and do the following:

s='abc'
c=G(s,33)()

which assigns 'Abc' to c.

My question is whether this is likely to work most of the time. In particular,

  • Can I always count on the list being lexicographically sorted by ASCII values?
  • Are there many changes to list of available between minor versions?
  • Do differences exist between implementations?

Also, has anyone used this before on PPCG?

\$\endgroup\$
  • \$\begingroup\$ I've seen similar things done with JavaScript and C#. \$\endgroup\$ – Peter Taylor Nov 2 '14 at 7:33
  • 2
    \$\begingroup\$ You can also do this with builtins: dir(__builtins__). And here's an alternative function: F=lambda o,i:getattr(o,dir(o)[i]). \$\endgroup\$ – grc Nov 2 '14 at 12:45
  • \$\begingroup\$ Also note that depending on which functions you plan on using, you could add the () to the end of F like so: F=lambda o,i:eval('o.'+dir(o)[i])() Then c=F('abc',33) will assign 'Abc' to c. \$\endgroup\$ – FryAmTheEggman Nov 2 '14 at 17:38
6
\$\begingroup\$

From the documentation:

The resulting list is sorted alphabetically

As for the differences, I think you will have to check (and specifying in your answer is probably a good idea). There are clear differences between python 2 and 3, for example, __nonzero__ was renamed to __bool__.

I have never heard of any differences between implementations, but I can't find any references on this.

I don't think this has been used before in part because it will rarely save you any characters over doing something like:

F=str.capitalize
s='abc'
c=F(s)

You would need to use several different functions from dir() in order for this to be worth it.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.