Functions as objects in Python: what exactly is stored in memory?

前端 未结 2 1325
我寻月下人不归
我寻月下人不归 2021-02-08 02:33

I\'ve been using Python for a while now to solve practical problems, but I still don\'t have a proper theoretical understanding of what\'s going on behind the hood. For example,

2条回答
  •  孤城傲影
    2021-02-08 02:59

    Functions are objects just like any other: they are instances of a type (or class). You can get the type of a function using type(f), where f is a function, or use the types module (types.FunctionType).

    When you define a function, Python builds a function object and assigns a name to it. This machinery is hidden behind the def statement, but it works the same as the instantiation of any other type.

    Which means that in Python, function definitions are executed, unlike in some other languages. Among other things, this means that functions don't exist until the flow of code reaches them, so you can't call a function before it has been defined.

    The inspect module lets you snoop around inside various kinds of objects. This table in its documentation is useful for seeing what kinds of components functions and related types of objects (such as methods) are made from, and how to get to them.

    The actual code inside a function becomes a code object, which contains the byte code that is executed by the Python interpreter. You can see this using the dis module.

    Looking at the help() of the types for functions and code objects is interesting, as it shows what arguments you need to pass in to build these objects. It is possible to make new functions from raw byte code, to copy byte code from one function to another but use a different closure, and so on.

    help(type(lambda: 0))
    help(type((lambda: 0).__code__))
    

    You can also build code objects using the compile() function and then build functions out of them.

    Fun Fact

    Any object whose type has a __call__() method is callable. Functions are callable, and their type has a __call__() method. Which is callable. Which means it, too, has a __call__() method, which has a __call__() method, ad nauseam, ad infinitum.

    How does a function actually get called, then? Python actually bypasses __call__ for objects with __call__ implemented in C, such as a Python function's __call__ method. Indeed, (lambda: 0).__call__ is a method-wrapper, which is used to wrap a C function.

提交回复
热议问题