# Functions in Python — def, Parameters, return and Scope

Source: https://skills101.in/learn/python/python-functions — Skills101 free tutorial (Python Programming). Updated 2026-11-09.

A **function** is a named block of code you can run again and again. It keeps programs short, readable and easy to test.

![A function definition labelled: the name (area), the parameters (length, width) and a default value (width=1); return sends the result back](https://skills101.in/learn-img/python/function-anatomy.svg)

## 1. Define and call

```python
def greet(name):
    print(f"Hello, {name}!")

greet("Asha")
greet("Ravi")
```

```text
Hello, Asha!
Hello, Ravi!
```

- `def` starts a function, followed by its **name** and **parameters** in brackets.
- The body is indented.
- Calling it with a value — an **argument** — runs the body.

## 2. return: give a value back

`print` only shows a value; `return` **sends it back** so you can use it.

```python
def area(length, width=1):
    return length * width

a = area(5, 3)
print(a, area(4), area(width=2, length=6))
```

```text
15 4 12
```

- `width=1` is a **default value** used when no width is given.
- `area(width=2, length=6)` uses **keyword arguments** — order doesn't matter.
- A function without `return` returns `None`.

### Returning several values

```python
def stats(nums):
    return min(nums), max(nums), sum(nums) / len(nums)

low, high, avg = stats([4, 8, 6])
print(low, high, avg)
```

```text
4 8 6.0
```

## 3. *args and **kwargs

- `*args` collects any number of positional arguments into a **tuple**.
- `**kwargs` collects keyword arguments into a **dictionary**.

```python
def total(*args):
    return sum(args)

def profile(**kwargs):
    for key, value in kwargs.items():
        print(key, "=", value)

print(total(1, 2, 3, 4))
profile(name="Neha", city="Indore")
```

```text
10
name = Neha
city = Indore
```

## 4. Scope: local vs global

Variables created inside a function are **local** — they exist only while it runs.

```python
count = 10          # global

def show():
    count = 99      # a NEW local variable
    print("inside:", count)

show()
print("outside:", count)
```

```text
inside: 99
outside: 10
```

To change a global variable inside a function, declare `global count` — but usually it's cleaner to **pass values in and return results**.

## 5. The mutable default trap

```python
def add_item(item, basket=[]):     # the same list is reused every call!
    basket.append(item)
    return basket

print(add_item("pen"))
print(add_item("book"))
```

```text
['pen']
['pen', 'book']
```

Fix it with `None`:

```python
def add_item(item, basket=None):
    if basket is None:
        basket = []
    basket.append(item)
    return basket

print(add_item("pen"))
print(add_item("book"))
```

```text
['pen']
['book']
```

This is a favourite interview question.

## 6. Docstrings

Put a description in triple quotes as the first line of the function. Tools and `help()` show it.

```python
def is_even(n):
    """Return True if n is even."""
    return n % 2 == 0

print(is_even(10), is_even.__doc__)
```

```text
True Return True if n is even.
```

## Common mistakes

- Using `print` inside a function when you need `return`.
- Forgetting the brackets when calling: `greet` vs `greet("Asha")`.
- Mutable default arguments (`def f(x=[])`).

## Quick recap

- `def name(params):` + indented body; call with `name(args)`.
- `return` gives a value back; no return → None.
- Defaults, keyword arguments, `*args` (tuple), `**kwargs` (dict).
- Local variables vanish after the call; prefer return over global.


Practice quiz and free certificate: https://skills101.in/learn/python/python-functions