Как заставить функцию изменять переменные во время цикла while? - PullRequest
0 голосов
/ 05 мая 2018
def lol(done, really_done):
    done = done + 1
    print(done)
    if done == 10:
        really_done = True

really_done = False
while really_done == False:
    done = 0
    lol(done, really_done)

поэтому, когда я запускаю этот код, он не меняет значение done, он всегда остается на 1. Я хочу, чтобы он изменился на 10 и остановил цикл while. Я только хочу это в этом типе модуля.

Ответы [ 3 ]

0 голосов
/ 05 мая 2018

Общая проблема заключается в том, что вы хотите сохранить состояние done и really_done при вызовах на lol. Есть несколько способов сделать это, поэтому я добавлю еще одну возможность.

Обычный способ сохранить состояние функции - это класс:

class Lol:

    def __init__(self, done=0, max_done=10):
        self.done = done
        self.max_done = max_done

    @property
    def really_done(self):
        self.done >= self.really_done

    def lol(self):
        self.done += 1

lol = Lol()
while not lol.really_done:
    lol.lol()
0 голосов
/ 05 мая 2018

Вы сбрасываете значение done каждый раз, когда запускаете цикл. Мало того - вы пытаетесь изменить значение глобальной переменной, но вместо этого изменяете значение простого параметра, поэтому lol(done) фактически ничего не делает.

Если вы хотите сохранить его в функции, вы должны использовать ключевое слово global, чтобы указать, что вы используете глобальные переменные:

def lol():
    global done
    global really_done

    done += 1
    really_done = done == 10

really_done = False
done = 0
while not really_done:
    lol()

Это должно работать, но это плохой код - вы не должны использовать global, если это не является реальной необходимостью . Не меняя большую часть своего кода, вы можете использовать return, чтобы сохранить ваш код чище:

def lol(done, really_done):
    done += 1
    really_done = done == 10

    return done, really_done

really_done = False
done = 0
while not really_done:
   done, really_done = lol(done, really_done)

Это делает его немного лучше. Тем не менее, мы можем решить все, просто зациклив range с for:

done = 0
for n in range(10):
    done += 1
print(done)
0 голосов
/ 05 мая 2018

Переменная really_done внутри функции lol и переменная really_done на уровне модуля находятся в разных областях (также обычно называемых пространствами имен ). Первая - это локальная переменная , а вторая - глобальная переменная .

def lol(done, really_done):
    done = done + 1               ---+
    print(done)                      |
    if done == 10:                   +--- the local scope (inside a `def`)
        really_done = True        ---+

really_done = False               ---+
while really_done == False:          |
    done = 0                         +--- the GLOBAL scope 
    lol(done, really_done)        ---+

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

def lol(done, really_done):
    done = done + 1
    print(done)
    if done == 10:
        really_done = True
    return done, really_done

done = 0
really_done = False
while really_done == False:
    done, really_done = lol(done, really_done)

Использование возвращаемого значения позволяет передавать информацию из локальной области (пространство имен функции) обратно в глобальную область (пространство имен модуля). Это аналогично тому, как передача аргументов функции позволяет получать информацию из внешней области (пространство имен модуля) в качестве информации в локальной области (пространство имен функции).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...