# syntactic sugar for def?

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Thu Sep 29 00:30:01 CEST 2011

```En Wed, 28 Sep 2011 18:51:00 -0300, Chris Kaynor
<ckaynor at zindagigames.com> escribió:

> On Wed, Sep 28, 2011 at 2:37 PM, Arnaud Delobelle <arnodel at gmail.com>
> wrote:
>> On 28 September 2011 22:26, Ethan Furman <ethan at stoneleaf.us> wrote:
>>> I remember that 'class' is sugar for type(....).
>>>
>>> I don't remember if 'def' is sugar for something besides lambda.
>>>
>>> Any clues for me?  Heck, I'll even be grateful for outright answers!
>>
>> It's not really sugar.  But I think you mean something like this:
>>
>>
>>>>> class A: pass
>> ...
>>>>> type(A)
>> <class 'type'>
>>>>> type is type(A)
>> True
>>
>> So the closest you get for functions will be:
>>
>>>>> def f(): pass
>> ...
>>>>> type(f)
>> <class 'function'>
>>
>> Try help(type(f)) to see how to use it to create a function object.
>> The problem is that you need to provide a code object, and the easiest
>> way to create a code object is to use a def statement :)
>
> I would say compile isn't too much harder to use:
>>>> c = compile('a = 123', 'test', 'exec')
>>>> d = {}
>>>> f = types.FunctionType(c, d, 'test')
>>>> f()
>>>> print d
> {'a': 123}
>
> Although it appears you get all of the variables defined as global
> apparently (try "f = types.FunctionType(c, globals(), 'test')"

I know no way of compiling a function body alone. Suppose you have this
function:

def foo(x):
print x
y = 2*x
return y

py> compile("  print x\n  y = 2*x\n  return y", "<string>", "exec")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
print x
^
IndentationError: unexpected indent
py> compile("print x\ny = 2*x\nreturn y", "<string>", "exec")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 3
SyntaxError: 'return' outside function

If you include the 'def' statement in the source string, the resulting
code object does not represent the function itself, but a "module"
defining it:

py> f = FunctionType(compile("def foo(x):\n print x\n y = 2*x\n return
y\n",
...       "<string>", "exec"), globals(), "foo")
py> f(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: <module>() takes no arguments (1 given)
py> dis.dis(f)
file "<string>", line 1>)
3 MAKE_FUNCTION            0
6 STORE_NAME               0 (foo)
12 RETURN_VALUE

To get at the actual function code, one should use
f.func_code.co_consts[0]; this would be the 'code' parameter for
types.FunctionType. Very complicated, really; nothing can beat the 'def'
statement for defining a function ;)

--
Gabriel Genellina

```