[Python-ideas] Anonymous blocks (again):

Steven D'Aprano steve at pearwood.info
Tue May 14 03:36:48 CEST 2013


On 14/05/13 03:23, Juancarlo Añez wrote:
> On Mon, May 13, 2013 at 11:58 AM, Terry Jan Reedy <tjreedy at udel.edu> wrote:
>
>> I disagree that the above is unpythonic. In Python, functions are objects
>> like everything else. Define them, pass them to functions, like anything
>> else. 'Unpythonic' is treating functions as special, other than that they
>> are called (have a call method).
>
>
> I beg to disagree. Functions are objects in python, but they get particular
> treatment.
>
> You can do:
>
> def f():
>      pass
> x = f
>
>
> But you can't do:
>
> x = def(): pass


That has nothing to do with *function objects*, and everything to do with the *keyword* def being a statement. If you avoid "def", you can do this:

x = lambda: None


or even this:

from types import FunctionType
x = FunctionType(code, globals, name, argdefs, closure)


Creating functions in this way is not exactly convenient, but it is possible.


There is a sense in which functions (and classes, and modules) are "different", not because Python chooses to treat them differently, but because they are inherently different. They are complex, almost free-form compound objects, and there is no "nice" syntax for creating them inside an expression. The closest Python comes to is lambda for functions, and that is limited to a single expression.

But regardless of the difficulty of creating a function object, once you have one, it is a first class object. Anything you can do with any other object, you can do with a function object. I'm with Terry on this: the code snippet you gave, where a function object is passed to another function, is a standard Python idiom and perfectly pythonic.

It's not uncommon to have to create data before you use it, even when you could create it in-place where you use it. E.g. we might choose to write:

data = [lots of items here]
x = some_value()
result = func(x, data)


instead of:

result = func(some_value(), [lots of items here])


to make the function call more readable, or to keep to some maximum line length, or in order to re-use some of the values. So even when we *can* embed values in a call, often we choose not to. The fact that you don't have a choice when it comes to functions is not a major problem. Even if you could write:

result = func(def (): lots of code goes here)


you probably shouldn't.



-- 
Steven


More information about the Python-ideas mailing list