Как работает вызов в 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

где self.next_pairи self.prev_pair— указатели на предыдущую и следующую ссылки соответственно.

Для настройки связанного списка у меня есть функция установки, которая выглядит следующим образом.

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

В ходе работы над программой я создаю словарь этих связанных списков, убираю ссылки с одних и добавляю их к другим. Между удалением и повторной установкой ссылки хранятся в промежуточном массиве.

В ходе отладки этой программы я понял, что мое понимание того, как Python передает аргументы функциям, ошибочно. Рассмотрим этот тестовый пример, который я написал:

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             

Когда я запускаю этот тест, я получаю следующий результат.

0
0
10
None
10108
0

Чего я не понимаю, так это почему второй вызов p.next_pairдает другой результат (10108), чем первый вызов ( 0) . installне возвращает объект Pair, который может перезаписать переданный (он возвращает None), и я не передаю установитьуказатель.

Мое понимание вызова по значению состоит в том, что интерпретатор копирует значения, переданные в функцию, оставляя переменные вызывающей стороны без изменений.Например, если я скажу

def foo(x):
     x = x+1
     return x

baz = 2
y = foo(baz)
print y
print baz

, то должны быть напечатаны 3и 2соответственно. И действительно, когда я проверяю это в интерпретаторе Python, происходит вот что.

Буду очень признателен, если кто-нибудь укажет мне правильное направление.

5
задан Pseudo-Gorgias 22 May 2012 в 01:21
поделиться