{"id":285,"date":"2026-04-19T20:55:16","date_gmt":"2026-04-19T20:55:16","guid":{"rendered":"http:\/\/askpython.com\/?p=285"},"modified":"2026-04-20T09:14:36","modified_gmt":"2026-04-20T09:14:36","slug":"python-functions","status":"publish","type":"post","link":"https:\/\/www.askpython.com\/python\/python-functions","title":{"rendered":"Python Functions"},"content":{"rendered":"\n<p>Functions are how you name behavior. Instead of writing the same five lines every time you need to validate user input, you write those five lines once, give them a name like <code>validate_input<\/code>, and call that name whenever you need it. That act of naming is the core purpose of a function and the starting point for everything else in this guide.<\/p>\n\n\n\n<p>This is not a beginner glossary entry. If you have written Python for a few weeks and find yourself copying blocks of code between files or writing the same logic in multiple places, this is where that habit ends. We will cover what functions actually do well, where they trip people up, and the patterns that make a function easy to test, read, and reuse.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Defining and Calling a Function<\/h2>\n\n\n\n<p>The syntax is straightforward. A function definition starts with <code>def<\/code>, followed by the name, parentheses for parameters, and a colon. The body is indented.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\ndef greet(name):\n    return f&quot;Hello, {name}&quot;\n\n<\/pre><\/div>\n\n\n<p>Calling the function is what actually runs the body:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\nmessage = greet(&quot;Alice&quot;)\nprint(message)  # Hello, Alice\n\n<\/pre><\/div>\n\n\n<p>If you omit the <code>return<\/code> statement, the function returns <code>None<\/code> by default. This is a common source of confusion when you expect a modified object or a computed value but get nothing back.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Parameters and Arguments<\/h2>\n\n\n\n<p>Parameters are the names in the function definition. Arguments are the values you pass when calling. Python separates these cleanly and gives you several ways to pass them.<\/p>\n\n\n\n<p><strong>Positional arguments<\/strong> are the default. They map to parameters by position:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\ndef power(base, exponent):\n    return base ** exponent\n\nresult = power(2, 3)  # base=2, exponent=3, result=8\n\n<\/pre><\/div>\n\n\n<p><strong>Keyword arguments<\/strong> let you name the parameter explicitly at the call site, which makes the intent clear and allows you to reorder:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\nresult = power(exponent=3, base=2)  # same result, unambiguous\n\n<\/pre><\/div>\n\n\n<p><strong>Default parameter values<\/strong> let callers omit arguments that have sensible defaults:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\ndef power(base, exponent=2):\n    return base ** exponent\n\nprint(power(4))    # 16, uses default exponent=2\nprint(power(4, 3)) # 64, overrides default\n\n<\/pre><\/div>\n\n\n<p>One rule that trips up newcomers: never use a mutable object like a list or dict as a default argument. Python evaluates defaults once at definition time, not at call time. If you mutate the default, that mutation persists across calls:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\n# Wrong\ndef add_item(item, items=&#x5B;]):\n    items.append(item)\n    return items\n\nprint(add_item(&quot;first&quot;))   # &#x5B;&#039;first&#039;]\nprint(add_item(&quot;second&quot;))  # &#x5B;&#039;first&#039;, &#039;second&#039;] \u2014 bug!\n\n# Correct\ndef add_item(item, items=None):\n    if items is None:\n        items = &#x5B;]\n    items.append(item)\n    return items\n\nprint(add_item(&quot;first&quot;))   # &#x5B;&#039;first&#039;]\nprint(add_item(&quot;second&quot;))  # &#x5B;&#039;second&#039;]\n\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Returning Values<\/h2>\n\n\n\n<p>A Python function can return any object. Returning multiple values is done by packing them into a tuple, which the caller can unpack:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\ndef divide_with_remainder(a, b):\n    quotient = a \/\/ b\n    remainder = a % b\n    return quotient, remainder\n\nq, r = divide_with_remainder(17, 5)\nprint(q, r)  # 3 2\n\n<\/pre><\/div>\n\n\n<p>The <code>return<\/code> statement ends the function immediately. Any code after a <code>return<\/code> inside the function body never runs. This is useful for early exits:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\ndef process(data):\n    if not data:\n        return None  # nothing to process\n    # expensive operations here\n    return transformed\n&lt;\/pre&gt;\n&lt;!-- \/wp:paragraph --&gt;\n\n&lt;!-- wp:heading --&gt;\n&lt;h2 class=&quot;wp-block-heading&quot;&gt;Variable Scope: Local, Global, Nonlocal&lt;\/h2&gt;\n&lt;!-- \/wp:heading --&gt;\n\n&lt;!-- wp:paragraph --&gt;\n&lt;p&gt;Variables defined inside a function are local to that function. They do not exist outside the function body, and they shadow any variables with the same name in the outer scope:&lt;\/p&gt;\n&lt;!-- \/wp:paragraph --&gt;\n\n&lt;!-- wp:syntaxhighlighter\/code {&quot;language&quot;:&quot;python&quot;} --&gt;\n&lt;pre class=&quot;wp-block-syntaxhighlighter-code&quot;&gt;\ndef scope_demo():\n    x = 10  # local variable\n    print(x)  # 10\n\nscope_demo()\nprint(x)  # NameError: x is not defined\n\n<\/pre><\/div>\n\n\n<p>To modify a global variable from inside a function, declare it with <code>global<\/code>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\ncounter = 0\n\ndef increment():\n    global counter\n    counter += 1\n\nincrement()\nprint(counter)  # 1\n\n<\/pre><\/div>\n\n\n<p>Global state makes testing difficult. If a function reads or modifies global variables, you cannot test it in isolation. Passing values as parameters and returning results is almost always the better design.<\/p>\n\n\n\n<p><code>nonlocal<\/code> is used when you have a nested function and need to modify a variable from the enclosing scope:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\ndef outer():\n    count = 0\n    def inner():\n        nonlocal count\n        count += 1\n        return count\n    return inner\n\ncounter_fn = outer()\nprint(counter_fn())  # 1\nprint(counter_fn())  # 2\n\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">*args and **kwargs: Flexible Parameters<\/h2>\n\n\n\n<p>The <code>*args<\/code> syntax lets a function accept any number of positional arguments. The function receives them as a tuple:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\ndef sum_all(*numbers):\n    total = 0\n    for n in numbers:\n        total += n\n    return total\n\nprint(sum_all(1, 2, 3))        # 6\nprint(sum_all(10, 20, 30, 40))  # 100\n\n<\/pre><\/div>\n\n\n<p><code>**kwargs<\/code> does the same for keyword arguments, packing them into a dictionary:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\ndef print_config(**settings):\n    for key, value in settings.items():\n        print(f&quot;{key} = {value}&quot;)\n\nprint_config(host=&quot;localhost&quot;, port=8080, debug=True)\n\n<\/pre><\/div>\n\n\n<p>You can combine all three in one function signature: positional, <code>*args<\/code>, and <code>**kwargs<\/code>. Python enforces the order: positional parameters first, then <code>*args<\/code>, then keyword-only parameters, then <code>**kwargs<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Functions as First-Class Objects<\/h2>\n\n\n\n<p>In Python, functions are objects. You can assign them to variables, pass them as arguments to other functions, return them from functions, and store them in data structures. This is not a special feature \u2014 it is built into the language design.<\/p>\n\n\n\n<p>Passing a function as an argument is the basis for callbacks, middleware, and strategy patterns:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\ndef apply_twice(fn, value):\n    return fn(fn(value))\n\ndef add_three(x):\n    return x + 3\n\nprint(apply_twice(add_three, 0))  # 6: (0+3)+3\n&lt;\/pre&gt;\n&lt;!-- \/wp:paragraph --&gt;\n\n&lt;!-- wp:paragraph --&gt;\n&lt;p&gt;Returning a function from a function is how decorators and factories work:&lt;\/p&gt;\n&lt;!-- \/wp:paragraph --&gt;\n\n&lt;!-- wp:syntaxhighlighter\/code {&quot;language&quot;:&quot;python&quot;} --&gt;\n&lt;pre class=&quot;wp-block-syntaxhighlighter-code&quot;&gt;\ndef make_multiplier(factor):\n    def multiply(x):\n        return x * factor\n    return multiply\n\ndouble = make_multiplier(2)\ntriple = make_multiplier(3)\nprint(double(5))   # 10\nprint(triple(5))   # 15\n\n<\/pre><\/div>\n\n\n<p><code>make_multiplier<\/code> returns a function that closes over the <code>factor<\/code> variable. That is a closure \u2014 which brings us to the next section.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Closures and Why They Matter<\/h2>\n\n\n\n<p>A closure is a function that remembers values from the scope where it was defined, even after that scope has finished executing. The <code>factor<\/code> in the <code>multiply<\/code> function is captured from <code>make_multiplier<\/code>&#8216;s local scope and stays alive as long as <code>multiply<\/code> exists.<\/p>\n\n\n\n<p>Closures show up constantly in real code. They are how you attach behavior to data without using a full class:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\ndef make_counter():\n    count = 0\n    def counter():\n        nonlocal count\n        count += 1\n        return count\n    return counter\n\nclick_counter = make_counter()\nprint(click_counter())  # 1\nprint(click_counter())  # 2\nprint(click_counter())  # 3\n\n<\/pre><\/div>\n\n\n<p>The inner <code>counter<\/code> function is a closure that holds onto <code>count<\/code>. Each call to <code>click_counter()<\/code> increments that captured value. You get stateful behavior without a class or any mutable global.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Lambda Functions<\/h2>\n\n\n\n<p>A lambda is an anonymous single-expression function. It is useful when you need a small throwaway function and writing a full <code>def<\/code> block feels like overkill:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\nnumbers = &#x5B;3, 1, 4, 1, 5, 9, 2, 6]\nsorted_by_mod_3 = sorted(numbers, key=lambda x: x % 3)\nprint(sorted_by_mod_3)  # &#x5B;3, 9, 6, 1, 1, 4, 5, 2]\n\n<\/pre><\/div>\n\n\n<p>The same logic as a named function:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\ndef mod_3(x):\n    return x % 3\n\nsorted_by_mod_3 = sorted(numbers, key=mod_3)\n\n<\/pre><\/div>\n\n\n<p>Use lambdas when the function is genuinely simple and used in one place. If the expression grows past a couple of lines or is used in multiple places, write a named function instead. A lambda can only contain an expression \u2014 not statements like assignment.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Type Hints and Docstrings<\/h2>\n\n\n\n<p>Type hints make it clear what a function expects and what it returns. They do not enforce anything at runtime by default, but they make code review faster, IDE support better, and bugs easier to catch with tools like mypy:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\ndef greet(name: str, times: int = 1) -&gt; str:\n    return (f&quot;Hello, {name}! &quot; * times).strip()\n\nprint(greet(&quot;Alice&quot;))       # Hello, Alice!\nprint(greet(&quot;Bob&quot;, 3))     # Hello, Bob! Hello, Bob! Hello, Bob!\n\n<\/pre><\/div>\n\n\n<p>Docstrings document what a function does. The minimal useful docstring covers the purpose, parameters, and return value:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n\ndef divide_with_remainder(a: int, b: int) -&gt; tuple&#x5B;int, int]:\n    &quot;&quot;&quot;Return the quotient and remainder of a divided by b.\n\n    Args:\n        a: The dividend.\n        b: The divisor (must be non-zero).\n\n    Returns:\n        A tuple of (quotient, remainder).\n    &quot;&quot;&quot;\n    if b == 0:\n        raise ValueError(&quot;divisor cannot be zero&quot;)\n    return a \/\/ b, a % b\n&lt;\/pre&gt;\n&lt;!-- \/wp:paragraph --&gt;\n\n&lt;!-- wp:paragraph --&gt;\n&lt;p&gt;A docstring that just says &quot;This function does something&quot; is not useful. A docstring that tells you what it returns, what exceptions it raises, and what the parameters mean is something you will thank yourself for six months later.&lt;\/p&gt;\n&lt;!-- \/wp:paragraph --&gt;\n\n&lt;!-- wp:heading --&gt;\n&lt;h2 class=&quot;wp-block-heading&quot;&gt;Frequently Asked Questions&lt;\/h2&gt;\n&lt;!-- \/wp:heading --&gt;\n\n&lt;!-- wp:heading {&quot;level&quot;:3} --&gt;\n&lt;h3 class=&quot;wp-block-heading&quot;&gt;Should I use global variables inside functions?&lt;\/h3&gt;\n&lt;!-- \/wp:heading --&gt;\n\n&lt;!-- wp:paragraph --&gt;\n&lt;p&gt;Almost never. Global state makes functions harder to test, harder to reason about, and a common source of subtle bugs when multiple parts of the code modify the same variable. Pass values as parameters and return results instead. If you find yourself using &lt;code&gt;global&lt;\/code&gt; in production code, it is a signal to reconsider the design.&lt;\/p&gt;\n&lt;!-- \/wp:paragraph --&gt;\n\n&lt;!-- wp:heading {&quot;level&quot;:3} --&gt;\n&lt;h3 class=&quot;wp-block-heading&quot;&gt;What is the difference between *args and a list parameter?&lt;\/h3&gt;\n&lt;!-- \/wp:heading --&gt;\n\n&lt;!-- wp:paragraph --&gt;\n&lt;p&gt;A list parameter requires the caller to pack arguments into a list before calling. &lt;code&gt;*args&lt;\/code&gt; lets the caller pass any number of positional arguments naturally, and the function receives them as a tuple. Both work, but &lt;code&gt;*args&lt;\/code&gt; is more readable when the function genuinely accepts a variable number of values:&lt;\/p&gt;\n&lt;!-- \/wp:paragraph --&gt;\n\n&lt;!-- wp:syntaxhighlighter\/code {&quot;language&quot;:&quot;python&quot;} --&gt;\n&lt;pre class=&quot;wp-block-syntaxhighlighter-code&quot;&gt;\n# Less natural for the caller\ndef sum_all(numbers):\n    return sum(numbers)\n\nsum_all(&#x5B;1, 2, 3])\n\n# More natural\ndef sum_all(*numbers):\n    return sum(numbers)\n\nsum_all(1, 2, 3)\n\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">When should I use a lambda instead of a named function?<\/h3>\n\n\n\n<p>Use a lambda when you need a small function for one specific use and defining it as a named function would add noise. <code>sorted(my_list, key=lambda x: x['score'])<\/code> is cleaner than defining a separate <code>get_score<\/code> function just for that one sort. If the lambda logic is complex enough that it needs a comment, use a named function instead.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Can a function return multiple values?<\/h3>\n\n\n\n<p>A function returns exactly one object. When you write <code>return a, b<\/code>, Python packages those into a tuple under the hood. The caller can then unpack them into separate variables, which makes it look like multiple return values. This is a common pattern and entirely intentional in Python.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How do closures differ from classes for maintaining state?<\/h3>\n\n\n\n<p>Classes and closures can both maintain state. Classes are more explicit and are the right tool when the state is complex or you need multiple methods. Closures are lighter weight and useful when you have a single piece of state or need a simple callable. Once a closure grows to the point where you are managing several captured variables, it is usually clearer to switch to a class.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>Functions are how you name behavior. Instead of writing the same five lines every time you need to validate user input, you write those five lines once, give them a name like validate_input, and call that name whenever you need it. That act of naming is the core purpose of a function and the starting [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":66383,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-285","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-python"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts\/285","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/comments?post=285"}],"version-history":[{"count":0,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/posts\/285\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/media\/66383"}],"wp:attachment":[{"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/media?parent=285"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/categories?post=285"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.askpython.com\/wp-json\/wp\/v2\/tags?post=285"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}