dir() and propertly list NEWBIE

Fredrik Lundh fredrik at pythonware.com
Wed Nov 24 09:55:44 CET 1999


<tiddlerdeja at my-deja.com> wrote:
> Is it possible to get the functions of an object using dir()? Rather
> that looking them up in a book/API.
>
> Similarly, If I can get an objects functions, is it possible then get a
> list of the possible parameters for that function?

the attached module contains all you need.

</F>

from the eff-bot archives:

#
# describeFunction.py
# $Id$
#
# utilities to describe functions, methods, and classes
#
# history:
# 96-10-27 fl     created
# 98-02-24 fl     added code to handle unpacked arguments
# 99-11-24 fl     sample code used bogus argument order
#
# notes:
# This has been tested with Python 1.4 and 1.5.  The code and
# function object attributes might change in future versions of
# Python.
#
# written by fredrik lundh.  last updated november 1999.
#
# fredrik at pythonware.com
# http://www.pythonware.com
#

import string

# --------------------------------------------------------------------
# code object attributes
# --------------------------------------------------------------------
# co_argcount   INT
# co_nlocals    INT
# co_flags      INT
#       CO_OPTIMIZED
#       CO_NEWLOCALS
#       CO_VARARGS
#       CO_VARKEYWORDS
# co_code       OBJECT
# co_consts     OBJECT
# co_names      OBJECT
# co_varnames   OBJECT
# co_filename   OBJECT
# co_name       OBJECT

# --------------------------------------------------------------------
# function object attributes
# --------------------------------------------------------------------
# func_code     OBJECT
# func_globals  OBJECT
# func_name     OBJECT (__name__)
# func_defaults OBJECT
# func_doc      OBJECT (__doc__)

# copied from Python header file
CO_OPTIMIZED = 0x0001
CO_NEWLOCALS = 0x0002
CO_VARARGS = 0x0004
CO_VARKEYWORDS = 0x0008

def _describe(func, name = None):
    # get argument list

    code = func.func_code

    n = code.co_argcount
    a = list(code.co_varnames[:n])
    p = 0
    for i in range(n):
        # anonymous arguments
        from dis import opname, HAVE_ARGUMENT    
        c = code.co_code
        if not a[i] or a[i][0] == ".":
            vars = []
            while p < len(c):
                v = ord(c[p])
                if v >= HAVE_ARGUMENT:
                    s, v = opname[v], ord(c[p+1]) + ord(c[p+2])*256
                    p = p + 3
                    if s == "UNPACK_TUPLE":
                        count = v
                    elif s == "STORE_FAST":
                        vars.append(code.co_varnames[v])
                        if len(vars) >= count:
                            break
                else:
                    p = p + 1
            if vars:
                a[i] = "(" + string.join(vars, ", ") + ")"
    if func.func_defaults:
        # defaults
        i = n - len(func.func_defaults)
        for d in func.func_defaults:
            a[i] = (a[i], d)
            i = i + 1
    if code.co_flags & CO_VARARGS:
        # extra arguments
        a.append("*"+code.co_varnames[n])
        n = n + 1
    if code.co_flags & CO_VARKEYWORDS:
        # extra keyword arguments
        a.append("**"+code.co_varnames[n])
        n = n + 1
    return a

def describe(func, name = None):
    "Return the function or method declaration as a string"

    # argument list
    a = _describe(func)
    args = []
    for arg in a:
        if type(arg) is type(""):
            args.append(arg)
        else:
            args.append("%s=%s" % (arg[0], repr(arg[1])))
    args = string.join(args, ", ")

    # function name
    if not name:
        name = func.func_name
        if name == "<lambda>":
            return "lambda %s" % args
    return "%s(%s)" % (name, args)


def __getmethods(c, m):
    for k, v in c.__dict__.items():
        if type(v) is type(__getmethods): # and k[0] != "_":
            if not m.has_key(k):
                m[k] = describe(v, k), c.__name__
    for c in c.__bases__:
        __getmethods(c, m)


def describe_class(cls):
    "Return a dictionary describing all methods available in a class"

    m = {}
    __getmethods(cls, m)
    return m


def describe_instance(self):
    "Return a dictionary describing all methods available in an instance"

    return describe_class(self.__class__)

#
# --------------------------------------------------------------------

if __name__ == "__main__":

    def foo(a, b=1, *c, **d):
        e = a + b + c
        f = None

    bar = lambda a: 0

    # based on an example from Duncan Booth
    def baz(a, (b, c, d), e, (f, g) = ('foo','bar')):
        pass

    print describe(foo)
    print describe(bar)
    print describe(baz)

# --- end of module ---





More information about the Python-list mailing list