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')"
> instead).

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)
   1           0 LOAD_CONST               0 (<code object foo at 00C0FAD0,  
file "<string>", line 1>)
               3 MAKE_FUNCTION            0
               6 STORE_NAME               0 (foo)
               9 LOAD_CONST               1 (None)
              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




More information about the Python-list mailing list