# 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
attributes:
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_defaults'
, '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'
>>> f.func_name
'f'

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>
Also:
>>> f.func_defaults
(23,)
and:
>>> f.func_globals
{'f': <function f at 0079A8AC>, '__doc__': None, '__name__': '__main__',
'__buil
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

So let's look at the code object:

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

Again, lots of stuff!  Most important:

>>> c.co_argcount
2
>>> c.co_names
('x', 'y')
>>> c.co_code
'\x7f\x01\x00\x7f\x01\x00|\x00\x00G|\x01\x00GHd\x00\x00S'
>>>

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
9 PRINT_ITEM
13 PRINT_ITEM
14 PRINT_NEWLINE
18 RETURN_VALUE

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

Alex

```