8

How come the dir() function in Python doesn't show all of the callable attributes?

import win32com.client

iTunes = win32com.client.gencache.EnsureDispatch("iTunes.Application")
currentTrack = win32com.client.CastTo(iTunes.CurrentTrack,"IITFileOrCDTrack")

print dir(currentTrack)

Result:

['AddArtworkFromFile', 'CLSID', 'Delete', 'GetITObjectIDs', 'Play', 'Reveal', 'UpdateInfoFromFile', 'UpdatePodcastFeed', '_ApplyTypes_', '__doc__', '__eq__', '__getattr__', '__init__', '__module__', '__ne__', '__repr__', '__setattr__', '_get_good_object_', '_get_good_single_object_', '_oleobj_', '_prop_map_get_', '_prop_map_put_', 'coclass_clsid']

print currentTrack.Location

Location is callable and returns the file path, but is not listed in the first result. It also doesn't show up with code completion tools. Is it because it's being fetched through a getter method? I see it listed under _prop_map_get_ and _prop_map_put_.

Also, why does currentTrack.Location return a file path when currentTrack._prop_map_get_['Location'] returns "(1610874880, 2, (8, 0), (), 'Location', None)?" Where is it getting the file path string?

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
tponthieux
  • 1,502
  • 5
  • 18
  • 30

2 Answers2

7

In python, an object can have a __getattr__ method. It will be invoked for any attribute access for a non-existent attribute. It looks like this object is using _prop_map_get_ as part of its implementation of __getattr__.

Since __getattr__ can do arbitrary computation to satisfy the attribute request, and can raise AttributeError for names it can't handle, there's no way from the outside to list all attributes that are available.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • +1 Understanding this was when the lightbulb really went on over my head for Python (well, for dynamic languages in general...) – bgporter Nov 05 '10 at 17:23
  • I'm curious as to how PythonWin can give me a correct listing of attributes for completion with a `COMObject` instance, and whether it's possible to do the same thing in Python code, or if it's doing something that the win32com package doesn't expose. – Wooble Aug 08 '12 at 15:02
4

Good one. Dir() does function correctly and the behavior is explainable.

Location is a property of currentTrack but is accessible only via currentTrack._prop_map_get_. The callable _prop_map_get_ is listed in dir(currentTrack). See getattr which is some how mapped to currentTrack._prop_map_get_

you will find various such cases in win32com which is a wrapper.

pyfunc
  • 65,343
  • 15
  • 148
  • 136