Fundamentals 20 min read

Master Python Functions: From Basics to Advanced Techniques

This comprehensive guide explains Python functions—their purpose, definition syntax, scope rules, built‑in statements like def, return, global, nonlocal, and lambda, various argument types, recursion, higher‑order functions, and functional tools such as map, filter, and reduce—complete with runnable code examples.

Ops Development Stories
Ops Development Stories
Ops Development Stories
Master Python Functions: From Basics to Advanced Techniques

Python Functions

Functions are the fundamental program structure Python provides to maximize code reuse and minimize redundancy; they also serve as a design tool that lets complex systems be broken into manageable components.

Purpose of Functions

Maximize code reuse and minimize redundancy

Decompose processes

Key statements and expressions related to functions:

Calls : my_function('Fir Arg','Sec Arg') def : def myfunction(fir_arg, sec_arg): return : return fir_arg + sec_arg global : global x; x = new_value nonlocal : nonlocal x; x = new_value yield :

def my_sqr(x):
    for i in range(x):
        yield i ** 2

lambda :

funcs = [lambda x: x*2, lambda x: x*3]

Writing Functions

The def statement creates a function object and binds it to a name; it is executed code, so a function is generated only when the def block runs. def can appear inside if, while, or even inside another def. def creates an object and assigns it to a variable. lambda creates a function object that can be used inline where a regular def cannot work. return sends a result object back to the caller. yield returns a result object but remembers the point of suspension. global declares a module‑level variable that can be assigned inside the function. nonlocal declares a variable from an enclosing function scope (available in Python 3.x).

Function arguments are passed by assignment; mutable objects are passed by reference, so changes affect the caller.

Parameters, return values, and variables do not need explicit declarations.

def Statement

The def syntax creates a function and binds it to a name:

def <function_name>([arg1, arg2, ...]):
    <statements>

The first line defines the function name, which is essentially a reference to the function object. Arguments may be zero or more. A return statement provides a value; if omitted, None is returned. A function can also contain yield to generate values. Because def is executable, the function is created at runtime.

>> def hanshu(x, y):
    return x * y
>>> hanshu('abc', 2)
'abcabc'
>>> hanshu(2, [1, 2, 3])
[1, 2, 3, 1, 2, 3]

The result of x*y depends on the runtime types of x and y because Python does not enforce static typing.

Python Scope

Scope concerns variable visibility. Using the same name in different scopes can lead to shadowing.

Variables defined inside a def are accessible only within that function.

Names defined outside a def are global; names defined inside are local and independent from outer names with the same identifier.

Global: defined outside any function.

Local: defined inside a function.

Enclosed: variables in nested functions have their own independent scopes.

Local vs Global Variables

>> x = 10  # global
>>> def funx():
...     x = 20  # local
...     print(x)
>>> print(x)  # prints global
10
>>> funx()    # prints local
20
>>> x = 10
>>> def funx():
...     print(x)  # no local assignment, uses global
>>> print(x)
10
>>> funx()
10

Scope Rules

Nested modules are in the global scope.

Global scope is limited to a single file.

Each function call creates a new local scope.

Variables are local unless declared global or nonlocal.

All other names are either local, global, or built‑in.

Variable lookup order:

Local name – has the variable been assigned locally?

Enclosing function’s locals – has the name been assigned in the nearest outer def or lambda?

Global name – is the name assigned at the module level?

Built‑in name – does Python provide a built‑in with that name?

global Statement

Use global inside a function to modify a variable defined at the module level.

>> g = 'global'
>>> l = 'global'
>>> def glo():
...     global g
...     g = 'local'
...     l = 'local'
>>> g
'global'
>>> l
'global'
>>> glo()
>>> g
'local'
>>> l
'global'

Other ways to affect globals include importing __main__ or using sys.modules['__main__'].

Scope and Nested Functions

Nested functions can access variables from their enclosing function. To expose an inner function, return it:

>> def outer():
...     def inner():
...         print('inner')
...     inner()
>>> outer()
inner

Factory Function

A factory returns a nested function that remembers the enclosing scope’s variables.

>> def printx(x):
...     def printy(y):
...         return x * y
...     return printy
>>> a = printx(3)
>>> a(2)
6
>>> a(3)
9

nonlocal Statement

nonlocal

makes a variable from the nearest enclosing function mutable.

>> x = 1
>>> def func1():
...     x = 2
...     def func2():
...         nonlocal x
...         x = 3
...         return x
...     func2()
...     print(x)
>>> func1()
3
>>> x
1

Parameters

Parameter Overview

Parameters (arguments) are the way values are passed into functions. Key points:

Parameters are bound to local variable names automatically.

Reassigning a parameter inside the function does not affect the caller.

Mutating a mutable argument (list, dict) can affect the caller.

Immutable objects (numbers, strings) are passed by value; mutable objects (lists, dicts) are passed by reference.

>> a = 3
>>> def printa(a):
...     a = a + 1
...     print(a)
>>> print(a)
3
>>> printa(a)
4
>>> print(a)
3

Argument Passing

Using a slice creates a new list, preventing modification of the original mutable argument:

>> def setlist(y):
...     y.append(3)
>>> a = [1, 2]
>>> setlist(a[:])
>>> a
[1, 2]
>>> setlist(a)
>>> a
[1, 2, 3]

Matching rules:

Positional: matched left‑to‑right.

Keyword: matched by parameter name.

Default: used when no value is supplied.

Variable‑length positional ( *args): collects extra positional arguments into a tuple.

Variable‑length keyword ( **kwargs): collects extra keyword arguments into a dict.

Keyword‑only: must be passed by name.

Parameter order: positional → keyword → dictionary unpacking.
>> def myfunc(a, b):
...     print(a, b)
>>> myfunc(1, 2)
1 2
>>> myfunc(b=1, a=2)
2 1

Matching Syntax

func(value)

– regular positional call. func(name=value) – keyword call. func(*sequence) – unpack iterable as positional arguments. func(**dict) – unpack dict as keyword arguments. def func(name) – regular parameter. def func(name=value) – default value. def func(*name) – variable‑length positional. def func(**name) – variable‑length keyword. def func(*arg, name) – keyword‑only after *.

Regular Parameter Example

>> def myfunc(a, b):
...     result = a + b
...     print(result)
>>> myfunc(1, 2)
3

Keyword Parameter Example

>> def myfunc(a, b):
...     result = a + b
...     print(result)
>>> myfunc(b=1, a=3)
4

Variable‑Length Positional (*args)

>> def myfunc(*a):
...     result = ''.join(a)
...     print(result)
>>> myfunc('1,', '2,', '3')
1,2,3
>>> myfunc('first,', *['second,', 'third'])
first,second,third

Variable‑Length Keyword (**kwargs)

>> def myfunc(**a):
...     print(a)
>>> myfunc(a='1', b='2')
{'a': '1', 'b': '2'}
>>> myfunc(a='1', b='2', **{'c': '3'})
{'a': '1', 'b': '2', 'c': '3'}

Keyword‑Only Parameters

>> def myfunc(*, b, **c):
...     print(b, c)
>>> myfunc(**{'b': 4})
4 {}

Advanced Function Usage

Recursive Functions

>> def mysum(s):
...     if not s:
...         return 0
...     else:
...         return s[0] + mysum(s[1:])
>>> mysum([1, 2, 3, 4])
10

Function Objects: Attributes and Annotations

Functions are objects; they can be assigned to other variables, stored in containers, and passed around.

>> def func(x):
...     print(x)
>>> func2 = func
>>> func2(2)
2

Storing functions in a list or tuple:

>> def myfunc(func_name, arg1):
...     func_name(arg1)
>>> li = [(func, 1), (func, 2), (func, 3)]
>>> for i in li:
...     myfunc(i[0], i[1])
1
2
3

Anonymous Functions: lambda

lambda

creates a function object without a name.

>> myfunc = lambda a: a*2
>>> myfunc(4)
8
>>> (lambda a, b: a*b)(5, 4)
20

Using lambda in collections simplifies code:

>> funclist = [lambda x: x**2, lambda x: x**3, lambda x: x**4]
>>> funclist[0](2)
4
>>> funclist[1](3)
27

Mapping Functions over Sequences: map

>> l = [1, 2, 3, 4]
>>> list(map(lambda x: x + 10, l))
[11, 12, 13, 14]

Functional Tool: filter

>> list(filter(lambda x: x > 1, [-1, 0, 1, 2, 3, 4, 5]))
[2, 3, 4, 5]

Functional Tool: reduce

reduce

resides in the functools module.

>> from functools import reduce
>>> reduce(lambda x, y: x + y, [1, 2, 3, 4])
10
>>> reduce(lambda x, y: x if x > y else y, [3, 5, 2, 6, 7, 4, 1, 9])
9
“善始者实繁,克终者盖寡。” —《谏太宗十思疏》
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

LambdaRecursionfunctionsargumentsscopehigher-order
Ops Development Stories
Written by

Ops Development Stories

Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.