You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
12 KiB
103 lines
12 KiB
<div class="section" id="function-definitions">
|
|
<span id="def"></span><span id="function"></span><span id="index-18"></span><h2>Function definitions</h2>
|
|
<p id="index-19">A function definition defines a user-defined function object (see section
|
|
<a class="reference internal" href="datamodel.html#types"><em>The standard type hierarchy</em></a>):</p>
|
|
<pre>
|
|
<strong id="grammar-token-funcdef">funcdef </strong> ::= [<a class="reference internal" href="#grammar-token-decorators"><tt class="xref docutils literal"><span class="pre">decorators</span></tt></a>] "def" <a class="reference internal" href="#grammar-token-funcname"><tt class="xref docutils literal"><span class="pre">funcname</span></tt></a> "(" [<a class="reference internal" href="#grammar-token-parameter_list"><tt class="xref docutils literal"><span class="pre">parameter_list</span></tt></a>] ")" ["->" <a class="reference internal" href="expressions.html#grammar-token-expression"><tt class="xref docutils literal"><span class="pre">expression</span></tt></a>] ":" <a class="reference internal" href="#grammar-token-suite"><tt class="xref docutils literal"><span class="pre">suite</span></tt></a>
|
|
<strong id="grammar-token-decorators">decorators </strong> ::= <a class="reference internal" href="#grammar-token-decorator"><tt class="xref docutils literal"><span class="pre">decorator</span></tt></a>+
|
|
<strong id="grammar-token-decorator">decorator </strong> ::= "@" <a class="reference internal" href="#grammar-token-dotted_name"><tt class="xref docutils literal"><span class="pre">dotted_name</span></tt></a> ["(" [<a class="reference internal" href="#grammar-token-parameter_list"><tt class="xref docutils literal"><span class="pre">parameter_list</span></tt></a> [","]] ")"] NEWLINE
|
|
<strong id="grammar-token-dotted_name">dotted_name </strong> ::= <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><tt class="xref docutils literal"><span class="pre">identifier</span></tt></a> ("." <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><tt class="xref docutils literal"><span class="pre">identifier</span></tt></a>)*
|
|
<strong id="grammar-token-parameter_list">parameter_list</strong> ::= (<a class="reference internal" href="#grammar-token-defparameter"><tt class="xref docutils literal"><span class="pre">defparameter</span></tt></a> ",")*
|
|
| "*" [<a class="reference internal" href="#grammar-token-parameter"><tt class="xref docutils literal"><span class="pre">parameter</span></tt></a>] ("," <a class="reference internal" href="#grammar-token-defparameter"><tt class="xref docutils literal"><span class="pre">defparameter</span></tt></a>)* ["," "**" <a class="reference internal" href="#grammar-token-parameter"><tt class="xref docutils literal"><span class="pre">parameter</span></tt></a>]
|
|
| "**" <a class="reference internal" href="#grammar-token-parameter"><tt class="xref docutils literal"><span class="pre">parameter</span></tt></a>
|
|
| <a class="reference internal" href="#grammar-token-defparameter"><tt class="xref docutils literal"><span class="pre">defparameter</span></tt></a> [","] )
|
|
<strong id="grammar-token-parameter">parameter </strong> ::= <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><tt class="xref docutils literal"><span class="pre">identifier</span></tt></a> [":" <a class="reference internal" href="expressions.html#grammar-token-expression"><tt class="xref docutils literal"><span class="pre">expression</span></tt></a>]
|
|
<strong id="grammar-token-defparameter">defparameter </strong> ::= <a class="reference internal" href="#grammar-token-parameter"><tt class="xref docutils literal"><span class="pre">parameter</span></tt></a> ["=" <a class="reference internal" href="expressions.html#grammar-token-expression"><tt class="xref docutils literal"><span class="pre">expression</span></tt></a>]
|
|
<strong id="grammar-token-funcname">funcname </strong> ::= <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><tt class="xref docutils literal"><span class="pre">identifier</span></tt></a>
|
|
</pre>
|
|
<p>A function definition is an executable statement. Its execution binds the
|
|
function name in the current local namespace to a function object (a wrapper
|
|
around the executable code for the function). This function object contains a
|
|
reference to the current global namespace as the global namespace to be used
|
|
when the function is called.</p>
|
|
<p>The function definition does not execute the function body; this gets executed
|
|
only when the function is called. <a class="footnote-reference" href="#id7" id="id3">[3]</a></p>
|
|
<p id="index-20">A function definition may be wrapped by one or more <a class="reference internal" href="../glossary.html#term-decorator"><em class="xref std std-term">decorator</em></a> expressions.
|
|
Decorator expressions are evaluated when the function is defined, in the scope
|
|
that contains the function definition. The result must be a callable, which is
|
|
invoked with the function object as the only argument. The returned value is
|
|
bound to the function name instead of the function object. Multiple decorators
|
|
are applied in nested fashion. For example, the following code</p>
|
|
<div class="highlight-python3"><div class="highlight"><pre><span class="nd">@f1</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
|
|
<span class="nd">@f2</span>
|
|
<span class="k">def</span> <span class="nf">func</span><span class="p">():</span> <span class="k">pass</span>
|
|
</pre></div>
|
|
</div>
|
|
<p>is equivalent to</p>
|
|
<div class="highlight-python3"><div class="highlight"><pre><span class="k">def</span> <span class="nf">func</span><span class="p">():</span> <span class="k">pass</span>
|
|
<span class="n">func</span> <span class="o">=</span> <span class="n">f1</span><span class="p">(</span><span class="n">arg</span><span class="p">)(</span><span class="n">f2</span><span class="p">(</span><span class="n">func</span><span class="p">))</span>
|
|
</pre></div>
|
|
</div>
|
|
<p id="index-21">When one or more <a class="reference internal" href="../glossary.html#term-parameter"><em class="xref std std-term">parameters</em></a> have the form <em>parameter</em> <tt class="docutils literal"><span class="pre">=</span></tt>
|
|
<em>expression</em>, the function is said to have “default parameter values.” For a
|
|
parameter with a default value, the corresponding <a class="reference internal" href="../glossary.html#term-argument"><em class="xref std std-term">argument</em></a> may be
|
|
omitted from a call, in which
|
|
case the parameter’s default value is substituted. If a parameter has a default
|
|
value, all following parameters up until the “<tt class="docutils literal"><span class="pre">*</span></tt>” must also have a default
|
|
value — this is a syntactic restriction that is not expressed by the grammar.</p>
|
|
<p><strong>Default parameter values are evaluated from left to right when the function
|
|
definition is executed.</strong> This means that the expression is evaluated once, when
|
|
the function is defined, and that the same “pre-computed” value is used for each
|
|
call. This is especially important to understand when a default parameter is a
|
|
mutable object, such as a list or a dictionary: if the function modifies the
|
|
object (e.g. by appending an item to a list), the default value is in effect
|
|
modified. This is generally not what was intended. A way around this is to use
|
|
<tt class="docutils literal"><span class="pre">None</span></tt> as the default, and explicitly test for it in the body of the function,
|
|
e.g.:</p>
|
|
<div class="highlight-python3"><div class="highlight"><pre><span class="k">def</span> <span class="nf">whats_on_the_telly</span><span class="p">(</span><span class="n">penguin</span><span class="o">=</span><span class="k">None</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">penguin</span> <span class="ow">is</span> <span class="k">None</span><span class="p">:</span>
|
|
<span class="n">penguin</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">penguin</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">"property of the zoo"</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">penguin</span>
|
|
</pre></div>
|
|
</div>
|
|
<p id="index-22">Function call semantics are described in more detail in section <a class="reference internal" href="expressions.html#calls"><em>Calls</em></a>. A
|
|
function call always assigns values to all parameters mentioned in the parameter
|
|
list, either from position arguments, from keyword arguments, or from default
|
|
values. If the form “<tt class="docutils literal"><span class="pre">*identifier</span></tt>” is present, it is initialized to a tuple
|
|
receiving any excess positional parameters, defaulting to the empty tuple. If
|
|
the form “<tt class="docutils literal"><span class="pre">**identifier</span></tt>” is present, it is initialized to a new dictionary
|
|
receiving any excess keyword arguments, defaulting to a new empty dictionary.
|
|
Parameters after “<tt class="docutils literal"><span class="pre">*</span></tt>” or “<tt class="docutils literal"><span class="pre">*identifier</span></tt>” are keyword-only parameters and
|
|
may only be passed used keyword arguments.</p>
|
|
<p id="index-23">Parameters may have annotations of the form “<tt class="docutils literal"><span class="pre">:</span> <span class="pre">expression</span></tt>” following the
|
|
parameter name. Any parameter may have an annotation even those of the form
|
|
<tt class="docutils literal"><span class="pre">*identifier</span></tt> or <tt class="docutils literal"><span class="pre">**identifier</span></tt>. Functions may have “return” annotation of
|
|
the form “<tt class="docutils literal"><span class="pre">-></span> <span class="pre">expression</span></tt>” after the parameter list. These annotations can be
|
|
any valid Python expression and are evaluated when the function definition is
|
|
executed. Annotations may be evaluated in a different order than they appear in
|
|
the source code. The presence of annotations does not change the semantics of a
|
|
function. The annotation values are available as values of a dictionary keyed
|
|
by the parameters’ names in the <tt class="xref py py-attr docutils literal"><span class="pre">__annotations__</span></tt> attribute of the
|
|
function object.</p>
|
|
<p id="index-24">It is also possible to create anonymous functions (functions not bound to a
|
|
name), for immediate use in expressions. This uses lambda expressions, described in
|
|
section <a class="reference internal" href="expressions.html#lambda"><em>Lambdas</em></a>. Note that the lambda expression is merely a shorthand for a
|
|
simplified function definition; a function defined in a “<a class="reference internal" href="#def"><tt class="xref std std-keyword docutils literal"><span class="pre">def</span></tt></a>”
|
|
statement can be passed around or assigned to another name just like a function
|
|
defined by a lambda expression. The “<a class="reference internal" href="#def"><tt class="xref std std-keyword docutils literal"><span class="pre">def</span></tt></a>” form is actually more powerful
|
|
since it allows the execution of multiple statements and annotations.</p>
|
|
<p><strong>Programmer’s note:</strong> Functions are first-class objects. A “<tt class="docutils literal"><span class="pre">def</span></tt>” statement
|
|
executed inside a function definition defines a local function that can be
|
|
returned or passed around. Free variables used in the nested function can
|
|
access the local variables of the function containing the def. See section
|
|
<a class="reference internal" href="executionmodel.html#naming"><em>Naming and binding</em></a> for details.</p>
|
|
<div class="admonition seealso">
|
|
<p class="first admonition-title">See also</p>
|
|
<dl class="last docutils">
|
|
<dt><span class="target" id="index-25"></span><a class="pep reference external" href="http://www.python.org/dev/peps/pep-3107"><strong>PEP 3107</strong></a> - Function Annotations</dt>
|
|
<dd>The original specification for function annotations.</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|