Referenciar primitivas globales contra objetos

¿Podría alguien explicar el siguiente resultado en Python?

Cuando se ejecuta el siguiente fragmento de código, Python emite un error, diciendo que se hizo referencia a la variable x antes de la asignación:

 x = 1 def increase_x(): x += 1 increase_x() 

La solución, por supuesto, sería incluir la línea global x después de la statement de la función para increase_x .

Sin embargo, cuando se ejecuta este siguiente fragmento de código, no hay ningún error, y el resultado es lo que espera:

 x = [2, -1, 4] def increase_x_elements(): for k in range(len(x)): x[k] += 1 increase_x_elements() 

¿Esto se debe a que los enteros son primitivos en Python (en lugar de objetos) y, por lo tanto, x en el primer fragmento es una primitiva almacenada en la memoria, mientras que x en el segundo fragmento hace referencia a un puntero a un objeto de lista?

Como señala Ffisegydd, no hay tal cosa como un primitivo en Python: todo es un objeto.

Sin embargo, debes tener en cuenta que estás haciendo dos cosas completamente diferentes en esos dos fragmentos. En el primero, estás volviendo a vincular x al valor de x + 1. Al intentar asignar a x, lo ha hecho de ámbito local, por lo que su referencia a x + 1 falla.

En el segundo fragmento, está modificando el contenido de x, en lugar de volver a encuadernarlo. Esto funciona porque las listas son mutables, pero la diferencia no es mutable frente a inmutable, sino mutante frente a reenlace: volver a encuadernar un objeto mutable fallaría, al igual que hacerlo con un entero.