Para un proyecto que estoy trabajando, estoy poniendo en práctica una estructura de datos de lista enlazada, que se basa en la idea de una pareja, que defino como:¿Cómo funciona la llamada en Python?
class Pair:
def __init__(self, name, prefs, score):
self.name = name
self.score = score
self.preferences = prefs
self.next_pair = 0
self.prev_pair = 0
donde self.next_pair
y son self.prev_pair
punteros a los enlaces anterior y siguiente, respectivamente.
Para configurar la lista enlazada, tengo una función de instalación que se ve así.
def install(i, pair):
flag = 0
try:
old_pair = pair_array[i]
while old_pair.next_pair != 0:
if old_pair == pair:
#if pair in remainders: remainders.remove(pair)
return 0
if old_pair.score < pair.score:
flag = 1
if old_pair.prev_pair == 0: # we are at the beginning
old_pair.prev_pair = pair
pair.next_pair = old_pair
pair_array[i] = pair
break
else: # we are not at the beginning
pair.prev_pair = old_pair.prev_pair
pair.next_pair = old_pair
old_pair.prev_pair = pair
pair.prev_pair.next_pair = pair
break
else:
old_pair = old_pair.next_pair
if flag==0:
if old_pair == pair:
#if pair in remainders: remainders.remove(pair)
return 0
if old_pair.score < pair.score:
if old_pair.prev_pair==0:
old_pair.prev_pair = pair
pair.next_pair = old_pair
pair_array[i] = pair
else:
pair.prev_pair = old_pair.prev_pair
pair.next_pair = old_pair
old_pair.prev_pair = pair
pair.prev_pair.next_pair = pair
else:
old_pair.next_pair = pair
pair.prev_pair = old_pair
except KeyError:
pair_array[i] = pair
pair.prev_pair = 0
pair.next_pair = 0
En el transcurso del programa, estoy construyendo un diccionario de estas listas enlazadas, y tomando enlaces fuera de algunos y la adición de ellos en otros. Entre ser recortado y reinstalado, los enlaces se almacenan en una matriz intermedia.
En el transcurso de la depuración de este programa, me he dado cuenta de que mi comprensión de la forma en que Python pasa los argumentos a las funciones es errónea. Considere este caso de prueba que escribí:
def test_install():
p = Pair(20000, [3, 1, 2, 50], 45)
print p.next_pair
print p.prev_pair
parse_and_get(g)
first_run()
rat = len(juggler_array)/len(circuit_array)
pref_size = get_pref_size()
print pref_size
print install(3, p)
print p.next_pair.name
print p.prev_pair
Cuando ejecuto esta prueba, obtengo el siguiente resultado.
0
0
10
None
10108
0
Lo que no entiendo es por qué la segunda llamada a p.next_pair
produce un resultado diferente (10108
) que la primera llamada (0
). install
no devuelve un objeto Pair
que pueda sobrescribir el que se entregó (devuelve None
), y no es como si estuviera pasando install
un puntero.
Mi comprensión de la llamada por valor es que el intérprete copia los valores pasados en una función, sin modificar las variables de la persona que llama. Por ejemplo, si digo
def foo(x):
x = x+1
return x
baz = 2
y = foo(baz)
print y
print baz
Entonces 3
y 2
se imprimirán, respectivamente. Y de hecho, cuando lo pruebo en el intérprete de Python, eso es lo que sucede.
Realmente agradecería que alguien me señale la dirección correcta aquí.
Python no tiene call-by-value. Tampoco tiene llamada por referencia. –
Para su información, puede usar el botón '{}' en la parte superior del cuadro de edición para sangrar un bloque de código seleccionado en 4 espacios: es una manera fácil de mantener la sangría correcta. – senderle
Esa clase 'Pair' parece que probablemente debería ser un' dict'. – Daenyth