tags:

views:

110

answers:

6

When studying a snippet of unknown Python code, I occasionally bump into the

varName.methodName()

pattern.

To figure out what's this, I shall study the code more, find where varName was instantiated, find its type. So if varName proves to be an instance of ClassName class, I would knew that methodName() is a method of ClassName.

Sometimes varName == self and methodName() is a method of this class, or a method inherited from some other class, if the current class is subclassing some other classes.

Are there quick ways / tools that could take 'methodName' as input, scan over all installed Python modules and show which classes have methodName()?

The closest thing related to this I know of is ipython. If I type a class name, then dot ('.') then TAB, it can show the class members. Instead of a class I could use a name of an object (which is an instance of a certain class) and it would work too. As soon as I choose a method name from the provided options, I can type '?' or '??' and get some help if there's a docstring.

I wonder if ipython can do some intelligent scanning based only on 'methodName' string.

If you know alternatives to ipython that could possibly help with this, please do suggest them.

Edit: as requested, I'm explicitly adding that I would like a way to find methods by method names not only in Python source code files. Some Python packages (notably PyQt) contain a lot of .so files, and ipython is able to do completions by presumably importing them first. So a plain text search like grep (or even ctags) won't do the trick here.

A: 

You could use the pydoc utility that comes with most versions of Python. On windows this is usually C:\PythonXX\Tools\Scripts\pydocgui.pyw (where XX is the Python version).

Running this will launch a small Tkinter window with a search box. You can search the auto-generated docs for all installed python modules, or open a browser on the top level documentation.

Dave Kirby
And most installations will have pydoc available from the Start Menu as the "Module Docs" item in the Python XX folder, if I'm not mistaken.
JAB
This is what I'm getting when launching the tkinter GUI and trying to search for anything: http://dpaste.org/p2NH/
jedi_coder
Update: the console version "pydoc -k keyword" doesn't raise any exceptions, but seems to be unable to find method names of classes from windowing toolkits like Qt and wxPython.
jedi_coder
A: 

If you use Eclipse with PyDev for your IDE, you can use the PyDev Globals Browser. You can search for modules, classes, methods and functions. Clicking on a result will open the source file and move the cursor to the line where the object is defined.

alt text

You can also hit F3 to jump to the definition of a variable that your cursor is on. For example if your cursor is on a line like import util, hitting F3 will open util.py.

FogleBird
+1  A: 

I sometimes inserted help(varName) into my code, so that when that particular function is run, the help file will show up instead. For example, if I have this code:

def foo(bar):
    bar.baz()

and I want to figure out what class bar is and what .baz does, I just insert this

def foo(bar):
    help(bar)
    help(bar.baz)
    bar.baz()

then run the script. Another way which is less invasive is to use print type(bar).

Lie Ryan
A: 

Given that your editor is vim, may I suggest ropevim. It uses rope, a Python refactoring library. Two of ropevim's features are "find occurrences" and "goto definition". Both of these will help you navigate your source tree.

Brandon Corfman
+3  A: 

You want Exuberant ctags (old ctags doesn't generate tags for Python).

Once you've installed (the way to do that depends on your platform), run it on your files:

$ /usr/local/bin/ctags *py

(you can run it multiple times to append tags to an existing tag file, have it recurse into subdirectories, etc, all with command-line options) and it makes a tags file like the following (for brevity I'm using a single Python file with one class defining a single method):

$ cat tags
!_TAG_FILE_FORMAT   2   /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED   1   /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR    Darren Hiebert  /[email protected]/
!_TAG_PROGRAM_NAME  Exuberant Ctags //
!_TAG_PROGRAM_URL   http://ctags.sourceforge.net    /official site/
!_TAG_PROGRAM_VERSION   5.7 //
Foo a.py    /^class Foo(object):$/;"    c
amethod a.py    /^  def amethod(self): pass$/;" m   class:Foo

Now, quoting this article:

Let say when you discover a function call which you wanna see the definition, simply point the cursor to that function and press ctrl ] and it will bring you there. If you want to go back to where you came from, simply press ctrl t. Instead of ctrl t, I like to use ctrl i and ctrl o to travel to forward and backward of the check points.

Also, control-P does (some attempt at) code completion for identifiers found in tags. (:help tags in vim will give you more details).

Alex Martelli
I just updated my question as suggested in comments. The update contains a motivation (I hope it's correct) why ctags is useful, but not always. Sorry for being obscure when initially asking my question. Feel free to update your answer if you know any other tricks that can cover the situation from the question update. Thank you.
jedi_coder
@jedi, I'd write a simple "adapter" of .so files to (fake) Python files on their way to ctags -- making ctags even _more_ exhuberant! -- and submit it as a user contributed add-on to ctags (if exhuberant ctags doesn't take plugins, then just wrap it!-).
Alex Martelli
+1  A: 

I'd take an interactive approach similar to Lie Ryan's: run the script in debug mode, set a break at the line of interest, and interactively query the variable in question.

This is a more robust approach than your requested "scan the source code looking for matching methodnames" because it's guaranteed to get you the variable you're actually wondering about, rather than returning a set of possibles.

Vicki Laidler