Python: локальные, глобальные переменные - PullRequest
0 голосов
/ 03 марта 2019

Я делаю новую программу на Python (Mastermind).У меня проблема со ссылками на переменные:

def user_turn():
    try_counter = 1
    user_code = []
    guessed_code = random_code()
    print("Twoja kolej na zgadywanie!")
    while try_counter <= max_tries and user_code != guessed_code:
        good_number, good_number_and_position = 0, 0
        appearance_types_guessing_code = [0 for i in range(types)]
        appearance_types_user_code = [0 for i in range(types)]
        user_code = input("Próba nr {}: ".format(try_counter))
        user_code = list(map(int, str(user_code)))
        count_xos()
        print_xos()
        try_counter += 1

    print_result_user_turn()

Тело функции print_xos():

def print_xos():
    for i in range(good_number_and_position):
        print("x", end='')
    for i in range(good_number):
        print("o", end='')
    print("")

И моя проблема в том, что в функции print_xos() переменные good_number иgood_number_and_position неизвестны, несмотря на то, что я объявил эти переменные в цикле while в теле функции user_turn().Как я могу решить эту проблему?Я не хочу отправлять ссылку в качестве аргумента функции.На мой взгляд, это не элегантно.Можно ли сделать это по-другому?

РЕДАКТИРОВАТЬ:

ОК, тогда я немного изменил код:

def user_turn():
    try_counter = 1
    user_code = []
    guessed_code = random_code()
    appearance_types_guessed_code = [0] * types
    how_many_appearance(guessed_code, appearance_types_guessed_code)
    print("Twoja kolej na zgadywanie!")
    while try_counter <= max_tries and user_code != guessed_code:
        good_number, good_number_and_position = 0, 0
        appearance_types_user_code = [0] * types
        user_code = input("Próba nr {}: ".format(try_counter))
        user_code = list(map(int, str(user_code)))
        how_many_appearance(user_code, appearance_types_user_code)
        print(appearance_types_guessed_code, appearance_types_user_code)
        count_xos(guessed_code, appearance_types_guessed_code, user_code, appearance_types_user_code, good_number, good_number_and_position)
        print(good_number_and_position, good_number)
        print_xos(good_number_and_position, good_number)
        try_counter += 1

    print_result_user_turn(guessed_code, user_code)

И тело функции count_xos:

def count_xos(guessed_code, appearance_types_guessed_code, user_code, appearance_types_user_code, good_number, good_number_and_position):
    for i in range(len(appearance_types_guessed_code)):
        good_number += np.min([appearance_types_guessed_code[i], appearance_types_user_code[i]])

    for i in range(code_size):
        if guessed_code[i] == user_code[i]:
            good_number_and_position += 1
            good_number -= 1
    print(good_number_and_position, good_number)

И я получил такой вывод:

RUNDA 1
Twoja kolej na zgadywanie!
Próba nr 1: 0011
[0, 2, 0, 1, 0, 0, 0, 1, 0, 0] [2, 2, 0, 0, 0, 0, 0, 0, 0, 0]
1 1
0 0

Вы можете быть уверены, что функция count_xos считает good_number, good_number_and_position рассчитывает правильно.Должно быть 1 1, но я не знаю, почему после запуска метода count_xos переменные good_number_and_position, good_number не меняются?

1 Ответ

0 голосов
/ 03 марта 2019

Ваша последняя попытка не возвращает номера, поэтому указанные номера не выполняются в вашей функции вызова.

Ваш код эквивалентен:

def one(aa,bb):
    aa *= 2
    bb *= 3
    print("In function", aa, bb)
    return aa, bb

a = 5
b = 11
one(a,b)      # does not reassign returned values - similar to not return anything like yours
print(a,b)

Вывод:

In function 10 33
5 11   

Вам необходимо вернуть и переназначить значения:

a,b = one(a,b) # reassign returns
print(a,b)

Вывод:

In function 10 33
10 33

Взгляните на Правила области видимости - лучше всего поддерживать область видимости как можно меньше и предоставлять данные для функции, которая им нужна.

Если вы изменяете вещи внутри функции, возвращайте ее новые значения и переназначайте их - это не требуется, если вы передаете список, это изменяемые ссылки и «автообновление», потому что вы оперируете с помощью ссылки на данные:

# same function used as above

a = 5
b = [11]
one(a,b)
print(a,b)

Вывод:

In function 10 [11, 11, 11]
5 [11, 11, 11]

Если вы посмотрите на id () переменных, вы увидите, что изменение aa приведет к повторению имени aaна другой идентификатор - но a снаружи все еще указывает на исходный.Изменение списка не изменяет идентификатор ссылки - он изменяет данные, на которые ссылается "ссылка":

def one_ids(aa,bb):
    print(id(aa),id(bb))
    aa *= 3   # modify an integer
    bb *= 3   # modify the list
    print(id(aa),id(bb))

a = 5
b = [11]
print(id(a),id(b))
one_ids(a,b)
print(id(a),id(b))

Вывод:

139647789732288   139647790644808   # id of a,b
139647789732288   139647790644808   # id of aa,bb before changing
139647789732**6**08   139647790644808   # id of aa,bb after changing
139647789732288   139647790644808   # id of a,b 

Вы можетеподробнее в Функция изменяет значения списка, а не значения переменных в Python - посмотрите, подходят ли вам эти объяснения лучше.

...