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:

<code>def &lt;function_name&gt;([arg1, arg2, ...]):
    &lt;statements&gt;</code>

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.

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

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

<code>>> 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
</code>

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.

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

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:

<code>>> def outer():
...     def inner():
...         print('inner')
...     inner()
>>> outer()
inner
</code>

Factory Function

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

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

nonlocal Statement

nonlocal

makes a variable from the nearest enclosing function mutable.

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

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.

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

Argument Passing

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

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

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.
<code>>> def myfunc(a, b):
...     print(a, b)
>>> myfunc(1, 2)
1 2
>>> myfunc(b=1, a=2)
2 1
</code>

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

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

Keyword Parameter Example

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

Variable‑Length Positional (*args)

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

Variable‑Length Keyword (**kwargs)

<code>>> 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'}
</code>

Keyword‑Only Parameters

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

Advanced Function Usage

Recursive Functions

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

Function Objects: Attributes and Annotations

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

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

Storing functions in a list or tuple:

<code>>> 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
</code>

Anonymous Functions: lambda

lambda

creates a function object without a name.

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

Using

lambda

in collections simplifies code:

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

Mapping Functions over Sequences: map

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

Functional Tool: filter

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

Functional Tool: reduce

reduce

resides in the

functools

module.

<code>>> 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
</code>
“善始者实繁,克终者盖寡。” —《谏太宗十思疏》
pythonlambdarecursionfunctionsargumentsscopehigher-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

login 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.