W3docs

Funzioni Python

Impara a definire e chiamare funzioni Python, usare parametri, argomenti predefiniti, *args, **kwargs, valori di ritorno, scope e docstring.

Una funzione è un blocco di codice riutilizzabile e con nome che esegue un compito specifico. Le funzioni ti permettono di scrivere la logica una sola volta e richiamarla da qualsiasi punto del programma, rendendo il codice più breve, più leggibile e più semplice da testare. Questo capitolo copre tutto ciò che ti serve per lavorare con sicurezza con le funzioni Python: definizione, parametri, valori di ritorno, argomenti predefiniti, *args e **kwargs, scope, docstring, type hint, ricorsione e utilizzo delle funzioni come oggetti di prima classe.

Definire una Funzione

Usa la parola chiave def, un nome, le parentesi e i due punti. Il corpo è indentato di un livello.

def greet(name):
    print("Hello, " + name)

La funzione non viene eseguita finché non la chiami. Al momento della definizione non accade nulla, tranne che Python memorizza l'oggetto funzione con il nome specificato.

Chiamare una Funzione

Passa gli argomenti tra le parentesi corrispondendo i nomi dei parametri della definizione.

python— editable, runs on the server

Valori di Ritorno

Una funzione può restituire un risultato al chiamante con l'istruzione return. Senza return, Python restituisce None.

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

result = add(3, 5)
print(result)  # 8

Una volta eseguita l'istruzione return, la funzione si interrompe immediatamente — qualsiasi codice che la segue nello stesso corpo della funzione è irraggiungibile.

Restituire Più Valori

Python ti permette di restituire più valori come tupla, che puoi destrutturare sul lato chiamante.

import math

def circle_stats(radius):
    area = math.pi * radius ** 2
    circumference = 2 * math.pi * radius
    return area, circumference

area, circ = circle_stats(5)
print(round(area, 2))   # 78.54
print(round(circ, 2))   # 31.42

Parametri e Argomenti

TermineSignificato
ParametroNome della variabile nella definizione della funzione
ArgomentoValore effettivo passato durante la chiamata alla funzione

Python supporta diversi modi per passare argomenti.

Argomenti Posizionali

Gli argomenti vengono abbinati ai parametri in ordine.

def describe(name, age):
    print(name, "is", age, "years old")

describe("Bob", 25)   # Bob is 25 years old

Argomenti per Nome (Keyword Arguments)

Puoi passare argomenti specificando il nome, in qualsiasi ordine.

describe(age=25, name="Bob")   # Bob is 25 years old

Valori Predefiniti dei Parametri

Fornisce un valore di fallback che viene usato quando il chiamante omette quell'argomento.

def greet(name="World"):
    print("Hello, " + name)

greet()         # Hello, World
greet("Alice")  # Hello, Alice

Attenzione: non usare mai un oggetto mutabile (lista, dict) come valore predefinito — viene creato una sola volta al momento della definizione e condiviso tra tutte le chiamate. Usa None come valore predefinito e crea l'oggetto all'interno del corpo della funzione.

# Correct pattern for a mutable default
def append_item(item, lst=None):
    if lst is None:
        lst = []
    lst.append(item)
    return lst

Argomenti Posizionali Arbitrari (*args)

Anteponi * al nome di un parametro per raccogliere un numero qualsiasi di argomenti posizionali in una tupla.

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

print(total(1, 2, 3))    # 6
print(total(10, 20))     # 30

Argomenti per Nome Arbitrari (**kwargs)

Anteponi ** per raccogliere un numero qualsiasi di argomenti per nome in un dizionario.

def describe_person(**info):
    for key, value in info.items():
        print(key + ": " + str(value))

describe_person(name="Alice", age=30, city="Paris")
# name: Alice
# age: 30
# city: Paris

Combinare i Tipi di Parametri

Quando mescoli tipi di parametri, l'ordine deve essere: posizionali, *args, solo per nome, **kwargs.

def log(level, *messages, separator=" | ", **meta):
    print(level.upper(), separator.join(messages), meta)

log("info", "started", "ready", separator=" — ", version="1.0")
# INFO started — ready {'version': '1.0'}

Scope delle Variabili

Le regole di scoping di Python seguono la regola LEGB: Local → Enclosing → Global → Built-in.

Una variabile definita all'interno di una funzione è locale — non è accessibile dall'esterno.

def my_func():
    x = 10          # local to my_func
    print(x)

my_func()
# print(x)  # NameError: name 'x' is not defined

Per leggere o modificare una variabile globale all'interno di una funzione, dichiarala con global.

x = 10

def change_x():
    global x
    x = 20

change_x()
print(x)   # 20

Usa global con parsimonia — le funzioni che dipendono dallo stato globale sono più difficili da testare e riutilizzare. Consulta Python Variables e Global Variables per un approfondimento sullo scope.

Docstring

Una docstring è una stringa letterale collocata immediatamente dopo la riga def. Documenta cosa fa la funzione, cosa accetta e cosa restituisce. Python la memorizza nell'attributo __doc__ della funzione e strumenti come help() la visualizzano.

def add(a, b):
    """Return the sum of a and b.

    Args:
        a: First number.
        b: Second number.

    Returns:
        The sum as a number.
    """
    return a + b

print(add.__doc__)
# Return the sum of a and b.
# ...

Type Hint

I type hint (PEP 484) ti permettono di annotare i tipi dei parametri e del valore di ritorno. Python non li verifica a runtime, ma editor, linter e mypy li usano per individuare i bug in anticipo.

def multiply(a: float, b: float) -> float:
    return a * b

print(multiply(3, 4))      # 12
print(multiply(2.5, 2.0))  # 5.0

Ricorsione

Una funzione può chiamare se stessa. Questo si chiama ricorsione ed è utile per problemi con una struttura naturalmente ricorsiva (alberi, fattoriali, ecc.). Ogni funzione ricorsiva ha bisogno di un caso base che arresti la ricorsione.

def factorial(n):
    if n == 0 or n == 1:   # base case
        return 1
    return n * factorial(n - 1)

print(factorial(5))   # 120
print(factorial(0))   # 1

Python limita la profondità di ricorsione (predefinita a 1000) per prevenire stack overflow. Per ricorsioni profonde, preferisci un approccio iterativo o usa sys.setrecursionlimit.

Funzioni come Oggetti di Prima Classe

In Python, le funzioni sono oggetti. Puoi memorizzarle in variabili, passarle come argomenti e restituirle da altre funzioni.

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

def double(n):
    return n * 2

print(apply(double, 7))   # 14

Questa è la base per le funzioni lambda, le funzioni di ordine superiore e i decoratori.

Funzioni Built-in vs. Funzioni Definite dall'Utente

Python include molte funzioni built-inprint(), len(), range(), sum(), sorted() — sempre disponibili senza alcun import. Le funzioni definite dall'utente sono quelle che scrivi con def. Entrambe seguono una sintassi di chiamata identica.

Buone Pratiche

  • Dai alle funzioni nomi che siano verbi: calculate_tax() è più chiaro di tax().
  • Fai una cosa sola: una funzione che valida, salva e invia un'email sono tre funzioni che aspettano di nascere.
  • Scrivi una docstring: anche una sola frase che descriva lo scopo è preziosa.
  • Evita gli effetti collaterali dove possibile: le funzioni che restituiscono valori e non modificano lo stato globale sono più facili da testare.
  • Mantieni le firme brevi: più di tre o quattro parametri è un segnale per raggruppare i dati correlati in una classe o un dict.
  • Usa i type hint: fungono da documentazione leggera e abilitano l'analisi statica.

Pratica

Pratica
Which keyword is used to define a function in Python?
Which keyword is used to define a function in Python?
Was this page helpful?