[МУЗЫКА] [МУЗЫКА] Мы совсем немного упоминали локальные переменные и параметры функции, а теперь давайте разберемся подробнее, что же это такое. Итак, сделаем очень простую функцию, которая печатает число, хранящееся в переменной a. Такое бессмысленное название, конечно, это непростительно, что я называю функцию f, а переменную a, но давайте, в этот раз можно. Итак, мы в основной программе кладем в переменную a значение 1, а в функции печатаем это значение. Давайте посмотрим, будет ли это работать. Запускаем, и да, напечаталась наша единица. Пока что все переменные, которые мы использовали, были глобальные. Что значит глобальные? Это значит, они видны из любого места программы, из основного кода и абсолютно из любой функции. Вот здесь наша переменная a глобальная, и когда мы печатаем какое-то значение функции, то печатаем значение этой глобальной переменной a. Что можно еще попробовать? Давайте попробуем сделать наоборот. В функции положить что-то в переменную a, вызвать эту функцию из основной программы и затем напечатать значение переменной a. И давайте запустим. Смотрите: она подчеркнула красным, значит, скорее всего, у нас ничего работать не будет. И действительно не работает. Она говорит: name a is not defined, то есть не определено значение, имя переменной a. Почему так произошло? Потому что функции, все переменные, значения которых вы изменяете, считаются локальными, то есть находящимися внутри этой функции. Правило простое: если не меняете значение, то переменная считается глобальной. Как только вы меняете какое-то значение, переменная считается локальной. Локальной — это значит, видна только внутри функции. И менять ее, обращаться к ней вы можете только внутри функции. Как только экземпляр функции закончился, переменная исчезает. И естественно, из основной программы вы доступ к этой переменной получить не можете. Давайте посмотрим еще разные интересные моменты. Итак, допустим, напечатаем это значение a функции, а в основной программе сделаем глобальную теперь переменную a со значением 0. И посмотрим, что будет происходить. Итак, запустим нашу программу. Напечаталось 1 и 0. Итак, мы положили в глобальную переменную a значение 0. Затем функция. Мы создали переменную, сделали a = 1. Как я уже говорил, присваивание значит — переменная локальная. То есть у нас внутри функции создалась переменная с тем же именем a, как и глобальная переменная. И мы напечатали собственно локальную переменную. Как только мы в функции создаем переменную с тем же названием, что и глобальная, мы уже к глобальной переменной с таким именем доступ получить даже на посмотреть не можем. Всё. То есть это два абсолютно разных a: a глобальное и a локальное. В основной программе используется, естественно, глобальная переменная a, а внутри функции — локальная переменная, поскольку ей было присваивание. И они друг на друга никак не влияют, что мы и увидели. Посмотрим: а, может быть, сработает вот такая штука. Попробуем напечатать переменную a в функции. Если мы так оставим, то это будет глобальная переменная. Давайте, кстати, проверим. Да, действительно, все окей, ничего не сломалось, напечаталось значение глобальной переменной a, посмотреть можно. А теперь сделаем какой-нибудь невероятный if. if false — if, который не выполняется никогда. И в этом if поменяем значение переменной. Вот нам уже подчеркнула красным, значит, все будет плохо, давайте убедимся. Действительно, все плохо. Она говорит, что к переменной a локальной доступ осуществляется перед присваиванием. То есть там еще ничего не лежит, а мы уже смотрим. С этой ошибкой мы могли уже столкнуться, если пытались использовать переменную до того, как мы ее инициализировали, положили что-то. То есть даже если этот if не выполняется никогда, если в теле функции, в командах, которые там выполняются, есть хоть одно присваивание, то переменная уже считается локальной. Всё. Таким образом, это правило работает не только для живого кода, но и для мертвого кода, который никогда не выполнится, оно тоже работает. Это делается заранее и без анализа, без выполнения программы. Хорошо, таким образом мы поняли, по какому признаку переменная внутри функции локальная, а по какому — глобальная. Но что же делать, если очень хочется изменить глобальную переменную из функции? Конечно, это желание странное. Вообще говоря, когда функции работают с глобальными переменными, это очень плохо. Почему? Потому что какой-то человек может взять ваш код, например, вы ее выложили в свободный доступ, и ему понравилась какая-то функция, которая делает что-то полезное. Он не хочет брать ваш код целиком, он хочет взять одну конкретную функцию. Берет ее, вставляет ее в свой код, и она не работает. Почему? Потому что вы использовали какие-то глобальные переменные, которых, естественно, у этого человека в коде нет. Понятно, что ему нужно разбираться, лезть куда-то, смотреть в вашем коде, что за глобальная переменная. Скорее всего, он просто плюнет на ваш код и напишет сам или возьмет чей-то чужой. И это будет довольно плохо. Таким образом, надо по возможности избегать использования вообще даже на посмотреть глобальных переменных внутри функции, и все, что нужно функции для работы, передавать в качестве параметра. Но, тем не менее, если вы вдруг будете читать чей-то чужой код, нужно понимать, что происходит. Итак, чтобы иметь возможность менять значения глобальных переменных внутри функции, нужно написать слово global, а затем перечислить все глобальные переменные через запятую, которые вы хотите поменять. Если бы у нас их было две, мы могли бы написать вот так. Но у нас одна, поэтому мы пишем всего одну переменную. И давайте посмотрим. Сначала напечатаем текущее значение, а потом изменим его. И должно вывестись 0 и 1. Сначала старое значение, которое у нас определено в основной программе, затем оно печатается внутри функции, и затем глобальное значение меняется, потому что теперь мы можем это делать. Поехали. Да, действительно, напечатался сначала 0, а затем напечаталась единица. То есть таким образом можно менять значения глобальных переменных из функции, но, опять же, еще раз напоминаю: по возможности все, что нужно для функции, передавать ей в качестве параметра. В принципе, вы можете, если что-то забыли, ничего страшного, можете ставить эксперименты. Среда программирования вам сразу подчеркнет какие-то неправильные вещи. Ну а если вы хотите более подробную информацию, то можете навести курсор, либо попытаться запустить вашу программу и почитать, в какой строке ошибка, и более какое-то подробное описание. Но и эксперименты такого рода, хотя правило простое, вы, опять же, можете ставить, если что-то забыли. Вспомните, что что-то там было про локальные и глобальные переменные. И разобраться, я думаю, вы сможете, довольно просто. Ну и опять же, у вас среда программирования подчеркивает разные нехорошие ситуации. Здесь аж целых две не очень хорошие ситуации: это не ошибки, но странности. Первая из них говорит о том, что у вас локальная переменная называется так же, как глобальная. И второе сообщение о том, что значение этой переменной сейчас никак не используется. Эти подсказки помогут вам разобраться, что происходит, и если происходит что-то неожиданное, не то, чего вы ожидаете, то, возможно, увидев, что у вас подчеркнуто такой не очень заметной серой линией, и наведя курсор туда, вы сможете прочитать что же там происходит, и это вас может навести на мысль. Например, вы хотели использовать глобальную переменную a, напечатать. А у вас подчеркивает серым. Или допустим, получили неожиданный эффект: ожидали увидеть нолик, а увидели единицу. И тогда смотрите, в чем у вас была ошибка, понимаете и исправляете. Например, вы хотели сделать что-то совершенно другое и случайно назвали переменную так же. Теперь мы назвали переменную по-другому, и никаких подчеркиваний у нас нет. Значит, все будет выполняться ровно так, как мы ожидаем. То есть при разработке среды программирования, старались учесть многочисленные стандартные ошибки, которые возникают у многих людей, и как-то попытаться помочь вам их исправить. Следуйте рекомендациям, и все будет получаться хорошо. [МУЗЫКА] [МУЗЫКА]