Python Functions | Parameters, Return Values, Lambdas, and Decorators

Python Functions | Parameters, Return Values, Lambdas, and Decorators

이 글의 핵심

Practical guide to Python functions: parameters, return values, lambdas, closures, and decorator basics—with runnable patterns.

Introduction: Functions as the basic unit of code

Functions are reusable blocks of work. In Python, functions are first-class objects: you can assign them to variables and pass them as arguments.


1. Function basics

Defining and calling functions

def greet(name):
    """
    Return a greeting for the given name.

    Args:
        name (str): Person to greet

    Returns:
        str: Greeting message
    """
    return f"Hello, {name}!"

print(greet("Bob"))

Multiple return values (tuples)

def get_user_info():
    name = "Bob"
    age = 25
    city = "Seoul"
    return name, age, city

name, age, city = get_user_info()
name, _, city = get_user_info()

Functions with no return value

def print_hello():
    print("Hello")

result = print_hello()
print(result)
print(type(result))

None patterns

def find_user(user_id):
    users = {1: "Bob", 2: "Alice"}
    return users.get(user_id)

user = find_user(5)
if user is None:
    print("Not found")

2. Parameters

Positional arguments

def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

Keyword arguments

def introduce(name, age, city):
    print(f"{name} ({age}) — {city}")

introduce("Bob", 25, "Seoul")
introduce(age=25, name="Bob", city="Seoul")
introduce("Bob", age=28, city="Daejeon")

Default arguments

def greet(name, greeting="Hello"):
    return f"{greeting}, {name}!"

print(greet("Bob"))
print(greet("Bob", "Hi"))

Never use a mutable default:

def add_item_bad(item, items=[]):
    items.append(item)
    return items

def add_item_safe(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

*args and **kwargs

def sum_all(*numbers):
    return sum(numbers)

def print_info(**kwargs):
    for k, v in kwargs.items():
        print(f"{k}: {v}")

def complex_func(a, b, *args, **kwargs):
    print(a, b, args, kwargs)

complex_func(1, 2, 3, 4, x=5, y=6)

Parameter order (typical): positional → *args → defaults (careful with Python 3.8+ keyword-only) → **kwargs.


3. Lambda functions

square = lambda x: x ** 2
print(square(5))

students = [("Bob", 85), ("Alice", 90), ("Carol", 80)]
print(sorted(students, key=lambda x: x[1], reverse=True))

numbers = [1, 2, 3, 4, 5]
print(list(map(lambda x: x ** 2, numbers)))
print(list(filter(lambda x: x % 2 == 0, numbers)))

Prefer list comprehensions over map/filter when readability wins.


4. Closures

def make_multiplier(n):
    def multiply(x):
        return x * n
    return multiply

times_3 = make_multiplier(3)
print(times_3(10))

nonlocal

def make_counter():
    count = 0
    def increment():
        nonlocal count
        count += 1
        return count
    return increment

5. Decorators (introduction)

Decorators wrap functions to add behavior (logging, timing, auth) without editing the original function’s body.

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("before")
        result = func(*args, **kwargs)
        print("after")
        return result
    return wrapper

@my_decorator
def add(a, b):
    return a + b

Examples: timing and caching

import time
from functools import lru_cache

def measure_time(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f"{func.__name__}: {time.time() - start:.4f}s")
        return result
    return wrapper

@lru_cache(maxsize=128)
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

6. Recursion and higher-order functions

def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)

def apply_operation(func, value):
    return func(value)

Best practices

  • Clear names, single responsibility, docstrings.
  • Avoid mutable defaults; use None and create a new list/dict inside.
  • Type hints (typing) help IDEs and mypy.
  • Prefer pure functions when possible.

Summary

  1. Define with def, return with return (implicit None if omitted).
  2. Positional, keyword, defaults, *args, **kwargs.
  3. Lambdas for tiny expressions; comprehensions often clearer than map/filter.
  4. Closures + nonlocal for enclosed state.
  5. Decorators compose behavior; use functools.wraps in production (see advanced post).

Next steps


Keywords (SEO)

Python functions, def, parameters, return, lambda, closure, decorator, *args, **kwargs, higher-order functions, recursion, type hints.