What is a Function?

Alex Martelli aleaxit at yahoo.com
Fri Aug 17 10:11:05 CEST 2001

"Patio87" <patio87 at aol.com> wrote in message
news:20010817033349.14357.00003437 at mb-mi.aol.com...
> What is a function?

It depends a bit on the context in which one asks -- the
mathematical definition, for example, doesn't quite match
the concept of function in most programming languages.

In Python, a function is an object with several important
    a function-name string
    a function-doc string
    most important, a code-object, which has:
        a tuple of 0 or more 'arguments', each of which has
            a name string
        a tuple of 0 or more other local variables, each of
            which has a name string
    possibly, default values for 0 or more arguments
    a reference to the dictionary of a module that supplies
        its globals
    possibly a reference to the enclosing-function
    possibly other user-defined attributes

e.g., consider:

>>> def f(x,y=23): print x,y

Now, f refers to a function object.  Let's see what it has:

>>> dir(f)
['__dict__', '__doc__', '__name__', 'func_closure', 'func_code',
, 'func_dict', 'func_doc', 'func_globals', 'func_name']

Wow, lots of stuff.  Well, many are two names for the same thing,
e.g. in the order we used above:

>>> f.__name__
>>> f.func_name

So these are both the function-name string, here 'f'.
The key thing:
>>> f.func_code
<code object f at 0079B9A0, file "<stdin>", line 1>
>>> f.func_defaults
>>> f.func_globals
{'f': <function f at 0079A8AC>, '__doc__': None, '__name__': '__main__',
tins__': <module '__builtin__' (built-in)>}

The other attributes of f are None in this case -- no dictionary (since
no user-defined attributes), no doc (we didn't give a documentation
string), no closure (it's not nested in any other function), so we won't
worry about them.

So let's look at the code object:

>>> c=f.func_code
>>> dir(c)
['co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename',
ineno', 'co_flags', 'co_freevars', 'co_lnotab', 'co_name', 'co_names',
ls', 'co_stacksize', 'co_varnames']

Again, lots of stuff!  Most important:

>>> c.co_argcount
>>> c.co_names
('x', 'y')
>>> c.co_code

Two arguments, their names, and a binary string of bytecode ready
for the interpreter.  We can look at the latter in more detail, too:

>>> import dis
>>> dis.disassemble(c)
          0 SET_LINENO               1

          3 SET_LINENO               1
          6 LOAD_FAST                0 (x)
          9 PRINT_ITEM
         10 LOAD_FAST                1 (y)
         13 PRINT_ITEM
         14 PRINT_NEWLINE
         15 LOAD_CONST               0 (None)
         18 RETURN_VALUE

But that's getting into a bit too much detail, I think.


More information about the Python-list mailing list