Взаимодействие с переменной используя функцию python
Добрый вечер, пытаюсь взаимодействовать со списком используя фунцию, но выводит ошибку.
from tkinter import * root=Tk() root.title("Bets") root.resizable(width=False, height=False) root.geometry("200x40") root.configure(bg='#bababa') listt=[] a=0 def bet(): a+=1 listt.append(int(a)) print(listt) btn1= Button(root,text=' ', bg='#a34040', fg='#fff', command=bet) btn1.place(x=10,y=10,width=180, height=20) root.mainloop()
Я хочу чтобы при нажатии кнопки список пополнялся на a. Я искал ответ, но везде как то странно объясняют и решают чуть другие задачи
explorer
На выходе конкретно что нужно получить? А то объяснения какие-то противоречивые, сбрасывается, увеличивается. Если увеличивающийся список, то можно просто объявить глобальную переменную.
from tkinter import * root = Tk() root.title("Bets") root.resizable(width=False, height=False) root.geometry("200x40") root.configure(bg='#bababa') listt = [] a = 0 def bet(): global a a += 1 listt.append(a) print(listt) btn1 = Button(root ,text=' ', bg='#a34040', fg='#fff', command=bet) btn1.place(x=10, y=10, width=180, height=20) root.mainloop()
explorer
Platinum
05.08.2018 1 093 2 506
Вам нужно проштудировать раздел «глобальные и локальные переменные», без этого делать в python нечего. Ошибка самая элементарная — переменная находится вне видимости функции. Её всего лишь нужно переместить в саму функцию. И приведение к типу int здесь лишнее, так как переменная и так цифра.
from tkinter import * root = Tk() root.title("Bets") root.resizable(width=False, height=False) root.geometry("200x40") root.configure(bg='#bababa') listt = [] def bet(): a = 0 a += 1 listt.append(int(a)) print(listt) btn1 = Button(root ,text=' ', bg='#a34040', fg='#fff', command=bet) btn1.place(x=10, y=10, width=180, height=20) root.mainloop()
Monotik
One Level
03.09.2020 24 0
Вам нужно проштудировать раздел «глобальные и локальные переменные», без этого делать в python нечего. Ошибка самая элементарная — переменная находится вне видимости функции. Её всего лишь нужно переместить в саму функцию. И приведение к типу int здесь лишнее, так как переменная и так цифра.
from tkinter import * root = Tk() root.title("Bets") root.resizable(width=False, height=False) root.geometry("200x40") root.configure(bg='#bababa') listt = [] def bet(): a = 0 a += 1 listt.append(int(a)) print(listt) btn1 = Button(root ,text=' ', bg='#a34040', fg='#fff', command=bet) btn1.place(x=10, y=10, width=180, height=20) root.mainloop()
Просто если я добавлю переменную в функцию, при повторном выполнении значение переменной сбрасывается. a увеличивается с 0 на 1, добавляется в список и снова сбрасывается до 0.
Возможно ли сохранить значение a при повторном использовании функции bet ?
Функции¶
Функции — это многократно используемые фрагменты программы. Они позволяют
дать имя определённому блоку команд с тем, чтобы впоследствии запускать этот блок по указанному имени в любом месте программы и сколь угодно много раз. Это называется вызовом функции. Мы уже использовали много встроенных функций, как то len и range .
Функция — это, пожалуй, наиболее важный строительный блок любой нетривиальной программы (на любом языке программирования), поэтому в этой главе мы рассмотрим различные аспекты функций.
Функции определяются при помощи зарезервированного слова def . После этого слова указывается имя функции, за которым следует пара скобок, в которых можно указать имена некоторых переменных, и заключительное двоеточие в конце строки. Далее следует блок команд, составляющих функцию. На примере можно видеть, что на самом деле это очень просто:
Пример: (сохраните как function1.py )
def sayHello(): print('Привет, Мир!') # блок, принадлежащий функции # Конец функции sayHello() # вызов функции sayHello() # ещё один вызов функции
Вывод:
$ python function1.py Привет, Мир! Привет, Мир!
Как это работает:
Мы определили функцию с именем sayHello , используя описанный выше синтаксис. Эта функция не принимает параметров, поэтому в скобках не объявлены какие-либо переменные. Параметры функции — это некие входные данные, которые мы можем передать функции, чтобы получить соответствующий им результат.
Обратите внимание, что мы можем вызывать одну и ту же функцию много раз, а значит нет необходимости писать один и тот же код снова и снова.
Параметры функций¶
Функции могут принимать параметры, т. е. некоторые значения, передаваемые функции для того, чтобы она что-либо сделала с ними. Эти параметры похожи на переменные, за исключением того, что значение этих переменных указывается при вызове функции, и во время работы функции им уже присвоены их значения.
Параметры указываются в скобках при объявлении функции и разделяются запятыми. Аналогично мы передаём значения, когда вызываем функцию. Обратите внимание на терминологию: имена, указанные в объявлении функции, называются параметрами, тогда как значения, которые вы передаёте в функцию при её вызове, — аргументами.
Пример: (сохраните как func_param.py )
def printMax(a, b): if a > b: print(a, 'максимально') elif a == b: print(a, 'равно', b) else: print(b, 'максимально') printMax(3, 4) # прямая передача значений x = 5 y = 7 printMax(x, y) # передача переменных в качестве аргументов
Вывод:
$ python func_param.py 4 максимально 7 максимально
Как это работает:
Здесь мы определили функцию с именем printMax , которая использует два параметра с именами a и b . Мы находим наибольшее число с применением простого оператора if..else и выводим это число.
При первом вызове функции printMax мы напрямую передаём числа в качестве аргументов. Во втором случае мы вызываем функцию с переменными в качестве аргументов. printMax(x, y) назначает значение аргумента x параметру a , а значение аргумента y — параметру b . В обоих случаях функция printMax работает одинаково.
Локальные переменные¶
При объявлении переменных внутри определения функции, они никоим образом не связаны с другими переменными с таким же именем за пределами функции — т. е. имена переменных являются локальными в функции. Это называется областью видимости переменной. Область видимости всех переменных ограничена блоком, в котором они объявлены, начиная с точки объявления имени.
Пример: (сохраните как func_local.py )
x = 50 def func(x): print('x равен', x) x = 2 print('Замена локального x на', x) func(x) print('x по-прежнему', x)
Вывод:
$ python func_local.py x равен 50 Замена локального x на 2 x по-прежнему 50
Как это работает:
При первом выводе значения, присвоенного имени x , в первой строке функции Python использует значение параметра, объявленного в основном блоке, выше определения функции.
Далее мы назначаем x значение 2 . Имя x локально для нашей функции. Поэтому когда мы заменяем значение x в функции, x , объявленный в основном блоке, остаётся незатронутым.
Последним вызовом функции print мы выводим значение x , указанное в основном блоке, подтверждая таким образом, что оно не изменилось при локальном присваивании значения в ранее вызванной функции.
Зарезервированное слово «global»¶
Чтобы присвоить некоторое значение переменной, определённой на высшем уровне программы (т. е. не в какой-либо области видимости, как то функции или классы), необходимо указать Python, что её имя не локально, а глобально (global). Сделаем это при помощи зарезервированного слова global . Без применения зарезервированного слова global невозможно присвоить значение переменной, определённой за пределами функции.
Можно использовать уже существующие значения переменных, определённых за пределами функции (при условии, что внутри функции не было объявлено переменной с таким же именем). Однако, это не приветствуется, и его следует избегать, поскольку человеку, читающему текст программы, будет непонятно, где находится объявление переменной. Использование зарезервированного слова global достаточно ясно показывает, что переменная объявлена в самом внешнем блоке.
Пример: (сохраните как func_global.py )
x = 50 def func(): global x print('x равно', x) x = 2 print('Заменяем глобальное значение x на', x) func() print('Значение x составляет', x)
Вывод:
$ python func_global.py x равно 50 Заменяем глобальное значение x на 2 Значение x составляет 2
Как это работает:
Зарезервированное слово global используется для того, чтобы объявить, что x — это глобальная переменная, а значит, когда мы присваиваем значение имени x внутри функции, это изменение отразится на значении переменной x в основном блоке программы.
Используя одно зарезервированное слово global , можно объявить сразу несколько переменных: global x, y, z .
Зарезервированное слово «nonlocal»¶
Мы увидели, как получать доступ к переменным в локальной и глобальной области видимости. Есть ещё один тип области видимости, называемый «нелокальной» ( nonlocal ) областью видимости, который представляет собой нечто среднее между первыми двумя. Нелокальные области видимости встречаются, когда вы определяете функции внутри функций.
Поскольку в Python всё является выполнимым кодом, вы можете определять функции где угодно.
Давайте рассмотрим пример:
# Filename: func_nonlocal.py def func_outer(): x = 2 print('x равно', x) def func_inner(): nonlocal x x = 5 func_inner() print('Локальное x сменилось на', x) func_outer()
Вывод:
$ python func_nonlocal.py x равно 2 Локальное x сменилось на 5
Как это работает:
Когда мы находимся внутри func_inner , переменная x , определённая в первой строке func_outer находится ни в локальной области видимости (определение переменной не входит в блок func_inner ), ни в глобальной области видимости (она также и не в основном блоке программы). Мы объявляем, что хотим использовать именно эту переменную x , следующим образом: nonlocal x .
Попробуйте заменить » nonlocal x » на » global x «, а затем удалить это зарезервированное слово, и пронаблюдайте за разницей между этими двумя случаями.
Значения аргументов по умолчанию¶
Зачастую часть параметров функций могут быть необязательными, и для них будут использоваться некоторые заданные значения по умолчанию, если пользователь не укажет собственных. Этого можно достичь с помощью значений аргументов по умолчанию. Их можно указать, добавив к имени параметра в определении функции оператор присваивания ( = ) с последующим значением.
Обратите внимание, что значение по умолчанию должно быть константой. Или точнее говоря, оно должно быть неизменным 1 — это объясняется подробнее в последующих главах. А пока запомните это.
Пример: (сохраните как func_default.py )
def say(message, times = 1): print(message * times) say('Привет') say('Мир', 5)
Вывод:
$ python func_default.py Привет МирМирМирМирМир
Как это работает:
Функция под именем say используется для вывода на экран строки указанное число раз. Если мы не указываем значения, по умолчанию строка выводится один раз. Мы достигаем этого указанием значения аргумента по умолчанию, равного 1 для параметра times 2 .
При первом вызове say мы указываем только строку, и функция выводит её один раз. При втором вызове say мы указываем также и аргумент 5 , обозначая таким образом, что мы хотим сказать 3 фразу 5 раз.
Значениями по умолчанию могут быть снабжены только параметры, находящиеся в конце списка параметров. Таким образом, в списке параметров функции параметр со значением по умолчанию не может предшествовать параметру без значения по умолчанию. Это связано с тем, что значения присваиваются параметрам в соответствии с их положением. Например, def func(a, b=5) допустимо, а def func(a=5, b) — не допустимо.
Ключевые аргументы¶
Если имеется некоторая функция с большим числом параметров, и при её вызове требуется указать только некоторые из них, значения этих параметров могут задаваться по их имени — это называется ключевые параметры. В этом случае для передачи аргументов функции используется имя (ключ) вместо позиции (как было до сих пор).
Есть два преимущества такого подхода: во-первых, использование функции становится легче, поскольку нет необходимости отслеживать порядок аргументов; во-вторых, можно задавать значения только некоторым избранным аргументам, при условии, что остальные параметры имеют значения аргумента по умолчанию.
Пример: (сохраните как func_key.py )
def func(a, b=5, c=10): print('a равно', a, ', b равно', b, ', а c равно', c) func(3, 7) func(25, c=24) func(c=50, a=100)
Вывод:
$ python func_key.py a равно 3, b равно 7, а c равно 10 a равно 25, b равно 5, а c равно 24 a равно 100, b равно 5, а c равно 50
Как это работает:
Функция с именем func имеет один параметр без значения по умолчанию, за которым следуют два параметра со значениями по умолчанию.
При первом вызове, func(3, 7) , параметр a получает значение 3 , параметр b получает значение 7 , а c получает своё значение по умолчанию, равное 10 .
При втором вызове func(25, c=24) переменная a получает значение 25 в силу позиции аргумента. После этого параметр c получает значение 24 по имени, т. е. как ключевой параметр. Переменная b получает значение по умолчанию, равное 5 .
При третьем обращении func(c=50, a=100) мы используем ключевые аргументы для всех указанных значений. Обратите внимание на то, что мы указываем значение для параметра c перед значением для a , даже несмотря на то, что в определении функции параметр a указан раньше c .
Переменное число параметров¶
Иногда бывает нужно определить функцию, способную принимать любое число параметров 4 . Этого можно достичь при помощи звёздочек (сохраните как function_varargs.py ):
def total(a=5, *numbers, **phonebook): print('a', a) #проход по всем элементам кортежа for single_item in numbers: print('single_item', single_item) #проход по всем элементам словаря for first_part, second_part in phonebook.items(): print(first_part,second_part) print(total(10,1,2,3,Jack=1123,John=2231,Inge=1560))
Вывод:
$ python function_varargs.py a 10 single_item 1 single_item 2 single_item 3 Inge 1560 John 2231 Jack 1123 None
Как это работает:
Когда мы объявляем параметр со звёздочкой (например, *param ), все позиционные аргументы начиная с этой позиции и до конца будут собраны в кортеж под именем param .
Аналогично, когда мы объявляем параметры с двумя звёздочками ( **param ), все ключевые аргументы начиная с этой позиции и до конца будут собраны в словарь под именем param .
Мы изучим кортежи и словари в одной из последующих глав.
Только ключевые параметры¶
Если некоторые ключевые параметры должны быть доступны только по ключу, а не как позиционные аргументы, их можно объявить после параметра со звёздочкой (сохраните как keyword_only.py ):
def total(initial=5, *numbers, extra_number): count = initial for number in numbers: count += number count += extra_number print(count) total(10, 1, 2, 3, extra_number=50) total(10, 1, 2, 3) # Вызовет ошибку, поскольку мы не указали значение # аргумента по умолчанию для 'extra_number'.
Вывод:
$ python keyword_only.py 66 Traceback (most recent call last): File "keyword_only.py", line 12, in total(10, 1, 2, 3) TypeError: total() needs keyword-only argument extra_number
Как это работает:
Объявление параметров после параметра со звёздочкой даёт только ключевые аргументы. Если для таких аргументов не указано значение по умолчанию, и оно не передано при вызове, обращение к функции вызовет ошибку, в чём мы только что убедились.
Обратите внимание на использование += , который представляет собой сокращённый оператор, позволяющий вместо x = x + y просто написать x += y .
Если вам нужны аргументы, передаваемые только по ключу, но не нужен параметр со звёздочкой, то можно просто указать одну звёздочку без указания имени: def total(initial=5, *, extra_number) .
Оператор «return»¶
Оператор return используется для возврата 5 из функции, т. е. для прекращения её работы и выхода из неё. При этом можно также вернуть некоторое значение из функции.
Пример: (сохраните как func_return.py )
#!/usr/bin/python # Filename: func_return.py def maximum(x, y): if x > y: return x elif x == y: return 'Числа равны.' else: return y print(maximum(2, 3))
Вывод:
$ python func_return.py 3
Как это работает:
Функция maximum возвращает максимальный из двух параметров, которые в данном случае передаются ей при вызове. Она использует обычный условный оператор if..else для определения наибольшего числа, а затем возвращает это число.
Обратите внимание, что оператор return без указания возвращаемого значения эквивалентен выражению return None . None — это специальный тип данных в Python, обозначающий ничего. К примеру, если значение переменной установлено в None , это означает, что ей не присвоено никакого значения.
Каждая функция содержит в неявной форме оператор return None в конце, если вы не указали своего собственного оператора return . В этом можно убедиться, запустив print(someFunction()) , где функция someFunction — это какая-нибудь функция, не имеющая оператора return в явном виде. Например:
def someFunction(): pass
Оператор pass используется в Python для обозначения пустого блока команд.
Существует встроенная функция max , в которой уже реализован функционал «поиск максимума», так что пользуйтесь этой встроенной функцией, где это возможно.
Строки документации¶
Python имеет остроумную особенность, называемую строками документации 6 , обычно обозначаемую сокращённо docstrings. Это очень важный инструмент, которым вы обязательно должны пользоваться, поскольку он помогает лучше документировать программу и облегчает её понимание. Поразительно, но строку документации можно получить, например, из функции, даже во время выполнения программы!
Пример: (сохраните как func_doc.py )
def printMax(x, y): '''Выводит максимальное из двух чисел. Оба значения должны быть целыми числами.''' x = int(x) # конвертируем в целые, если возможно y = int(y) if x > y: print(x, 'наибольшее') else: print(y, 'наибольшее') printMax(3, 5) print(printMax.__doc__)
Вывод:
$ python func_doc.py 5 наибольшее Выводит максимальное из двух чисел. Оба значения должны быть целыми числами.
Как это работает:
Строка в первой логической строке функции является строкой документации для этой функции. Обратите внимание на то, что строки документации применимы также к модулям и классам, о которых мы узнаем в соответствующих главах.
Строки документации принято записывать в форме многострочной 7 строки, где первая строка начинается с заглавной буквы и заканчивается точкой. Вторая строка оставляется пустой, а подробное описание начинается с третьей. Вам настоятельно рекомендуется следовать такому формату для всех строк документации всех ваших нетривиальных функций.
Доступ к строке документации функции printMax можно получить с помощью атрибута этой функции (т. е. имени, принадлежащего ей) __doc__ (обратите внимание на двойное подчёркивание). Просто помните, что Python представляет всё в виде объектов, включая функции. Мы узнаем больше об объектах в главе о классах.
Если вы пользовались функцией help() в Python, значит вы уже видели строки документации. Эта функция просто-напросто считывает атрибут __doc__ соответствующей функции и аккуратно выводит его на экран. Вы можете проверить её на рассмотренной выше функции: просто включите help(printMax) в текст программы. Не забудьте нажать клавишу q для выхода из справки ( help ).
Точно так же автоматические инструменты могут получать документацию из программы. Именно поэтому я настоятельно рекомендую вам использовать строки документации для любой нетривиальной функции, которую вы пишете. Команда pydoc , поставляемая вместе с пакетом Python, работает аналогично функции help() .
Аннотации¶
Функции имеют ещё одну дополнительную возможность, называемую аннотациями, которые предоставляют отличный способ сопровождения каждого параметра, равно как и возвращаемого значения дополнительной информацией. Поскольку сам язык Python не интерпретирует эти аннотации каким-либо способом (этот функционал отводится посторонним библиотекам), мы опустим эту возможность из нашего обсуждения.
Резюме¶
Мы рассмотрели достаточно много аспектов функций, но тем не менее, вы должны понимать, что это далеко не все их аспекты. В то же время, мы охватили большинство того, с чем вы будете сталкиваться при повседневном использовании функций в Python.
Далее мы увидим, как использовать и создавать модули Python.
- «immutable» в терминологии Python (прим. перев.) ↩
- times — англ. «раз» (прим. перев.) ↩
- say — англ. «сказать» (прим. перев.) ↩
- VarArgs — от англ. «Variable number of Arguments» — «переменное число аргументов» (прим. перев.) ↩
- return — англ. «возврат» (прим. перев.) ↩
- DocString — от англ. «Documentation String» — «строка документации» (прим. перев.) ↩
- т. е. строки, содержащей символы перевода строки. (прим. перев) ↩
Переменные
Переменная — это имя, которое используется для ссылки на область памяти. Переменная Python также известна как идентификатор и используется для хранения значения.
В Python нам необязательно указывать тип переменной, поскольку Python является языком с динамической типизацией.
Имена переменных могут состоять как из букв, так и из цифр, но они должны начинаться с буквы или символа подчеркивания.
Рекомендуется использовать строчные буквы для имени переменной. Rahul и rahul — это две разные переменные, т.к. имена переменных регистрозависимы.
Именование идентификаторов
Переменные являются примером идентификаторов. Правила присвоения имени идентификатору приведены ниже.
- Первый символ переменной должен быть буквой или символом подчеркивания ( _ ).
- Все символы, кроме первого, могут быть: строчными (a-z), прописными (A-Z), подчеркиванием или цифрами (0-9).
- Имя идентификатора не должно содержать пробелов или специальных символов (!, @, #, %, ^, &, *).
- Имя идентификатора не должно быть похоже ни на одно ключевое слово, определенное в языке.
- Имена идентификаторов чувствительны к регистру; например, myname и MyName — не одно и то же.
- Примеры допустимых идентификаторов: a123, _n, n_9 и т.д.
- Примеры недопустимых идентификаторов: 1a, n%4, n9 и т.д.
Объявление переменных и присвоение значений
Python не обязывает нас объявлять переменную перед ее использованием в приложении. Он позволяет нам создать переменную в нужный момент.
В Python нам не нужно объявлять переменную в явном виде. Когда мы присваиваем переменной какое-либо значение, эта переменная объявляется автоматически.
Оператор = используется для присвоения значения переменной.
Ссылки на объекты
Необходимо понять, как работает интерпретатор Python, когда мы объявляем переменную. Процесс обращения с переменными несколько отличается от многих других языков программирования.
Python — объектно-ориентированный язык программирования, поэтому каждый элемент данных принадлежит к определенному типу класса. Рассмотрим следующий пример.
print("John")
В приведенном выше операторе print мы создали строковый объект. Давайте проверим его тип с помощью встроенной в Python функции type() .
type("John")
В Python переменные — это символическое имя, которое является ссылкой или указателем на объект. Переменные используются для обозначения объектов этим именем.
Давайте разберем следующий пример
a = 50
На изображении выше переменная a относится к целочисленному объекту.
Предположим, что мы присвоим целочисленное значение 50 новой переменной b .
a = 50 b = a

Переменная b ссылается на тот же объект, на который указывает a , потому что Python не создает другой объект.
Давайте присвоим новое значение b . Теперь обе переменные будут ссылаться на разные объекты.
a = 50 b = 100

Python эффективно управляет памятью, если мы присваиваем одной и той же переменной два разных значения.
Идентификация объекта
В Python каждый созданный объект идентифицируется уникально. Python гарантирует, что никакие два объекта не будут иметь одинаковый идентификатор. Для определения идентификатора объекта используется встроенная функция id() . Рассмотрим следующий пример.
a = 50 b = a print(id(a)) print(id(b)) # Reassigned variable a a = 500 print(id(a))
140734982691168 140734982691168 2822056960944
Мы присвоили b = a , a и b указывают на один и тот же объект. Когда мы проверили функцией id() , она вернула то же самое число. Мы изменили значение a на 500 ; затем он сослался на новый идентификатор объекта.
Имена переменных в python
Мы уже обсуждали, как объявить допустимую переменную. Имена переменных могут быть любой длины, могут содержать прописные и строчные буквы (от A до Z, от a до z), цифры (0-9) и символ подчеркивания(_). Рассмотрим следующий пример допустимых имен переменных.
name = "Devansh" age = 20 marks = 80.50 print(name) print(age) print(marks)
Рассмотрим следующие имена допустимых переменных.
name = "A" Name = "B" naMe = "C" NAME = "D" n_a_m_e = "E" _name = "F" name_ = "G" _name_ = "H" na56me = "I" print(name,Name,naMe,NAME,n_a_m_e, NAME, n_a_m_e, _name, name_,_name, na56me)
В приведенном выше примере мы объявили несколько допустимых имен переменных, таких как name, name , и т.д. Но это не рекомендуется, так как при чтении кода это может привести к путанице. Имя переменной должно быть описательным, чтобы сделать код более читабельным.
Описательные имена переменных, состоящие из нескольких слов могут быть определены следующим способом.
- Camel Case — В верблюжьем регистре каждое слово или аббревиатура в середине начинается с заглавной буквы. Не допускается вмешательство пробелов. Например — nameOfStudent , valueOfVaraible и т.д.
- Pascal Case — То же самое, что и верблюжий регистр, но здесь первое слово также является заглавным. Например — NameOfStudent и т.д.
- Snake Case — В змеином регистре слова разделяются подчеркиванием. Например — name_of_student и т.д.
Множественная инициализация переменных в Python
Python позволяет присваивать значение нескольким переменным в одном операторе, что также известно как множественное присваивание.
Мы можем применять множественные присваивания двумя способами: либо присваивая одно значение нескольким переменным, либо присваивая несколько значений нескольким переменным. Рассмотрим следующий пример.
- Присвоение одного значения нескольким переменным
x=y=z=50 print(x) print(y) print(z)
Значения будут присваиваться в том порядке, в котором появляются переменные.
Типы переменных Python
В Python существует два типа переменных — локальная переменная и глобальная переменная.
Локальные переменные в Python
Локальные переменные — это переменные, объявленные внутри функции и имеющие область видимости в пределах функции. Давайте разберем следующий пример.
# Declaring a function def add(): # Defining local variables. a = 20 b = 30 c = a + b print("The sum is:", c) # Calling a function add()
В приведенном выше коде мы объявили функцию add() и назначили несколько переменных внутри функции. Эти переменные будут называться локальными переменными, которые имеют область видимости только внутри функции. Если мы попытаемся использовать их вне функции, то получим следующую ошибку.
add() # Accessing local variable outside the function print(a)
The sum is: 50 print(a) NameError: name ‘a’ is not defined
Мы попытались использовать локальную переменную вне ее области видимости; это вызвало ошибку NameError .
Глобальные переменные в Python
Глобальные переменные могут использоваться во всей программе, и область их действия распространяется на всю программу. Мы можем использовать глобальные переменные внутри или вне функции.
Переменная, объявленная вне функции, по умолчанию является глобальной переменной. Python предоставляет ключевое слово global для использования глобальной переменной внутри функции. Если мы не используем ключевое слово global , функция рассматривает ее как локальную переменную. Давайте разберем следующий пример.
# Declare a variable and initialize it x = 101 # Global variable in function def mainFunction(): # printing a global variable global x print(x) # modifying a global variable x = 'Welcome To Javatpoint' print(x) mainFunction() print(x)
101 Welcome To Javatpoint Welcome To Javatpoint
В приведенном выше коде мы объявляем глобальную переменную x и присваиваем ей значение. Затем мы определили функцию и обратились к объявленной переменной с помощью ключевого слова global внутри функции. Теперь мы можем изменить ее значение. Затем мы присвоили переменной x новое строковое значение.
Теперь мы вызвали функцию и вывели значение переменной x . Она вывела только что присвоенное значение.
Удаление переменной в Python
Мы можем удалить переменную с помощью ключевого слова del . Синтаксис приведен ниже.
В следующем примере мы создаем переменную x и присваиваем ей значение. Мы удалили переменную x , и при печати получаем ошибку variable x is not defined. Переменная x больше не будет использоваться в будущем.
# Assigning a value to x x = 6 print(x) # deleting a variable. del x print(x)
6 Traceback (most recent call last): File «C:/Users/DEVANSH SHARMA/PycharmProjects/Hello/multiprocessing.py», line 389, in print(x) NameError: name ‘x’ is not defined
Максимально возможное значение целого числа в Python
В отличие от других языков программирования, в Python нет типов данных long int или float. Он рассматривает все целочисленные значения как тип данных int. Здесь возникает вопрос. Какое максимальное значение может хранить переменная в Python? Рассмотрим следующий пример.
# A Python program to display that we can store # large numbers in Python a = 10000000000000000000000000000000000000000000 a = a + 1 print(type(a)) print (a)
Как видно из примера выше, мы присвоили переменной x большое целочисленное значение и проверили его тип. Он вывел class , а не long int . Следовательно, число не ограничено битами, и мы можем расширять его до предела нашей памяти.
В Python нет специального типа данных для хранения больших чисел.
Вывод одной или нескольких переменных в Python
Мы можем печатать несколько переменных в одном операторе print . Ниже приведены примеры печати одного и нескольких значений.
Пример — 1 (печать одной переменной)
# printing single value a = 5 print(a) print((a))
Пример — 2 (Печать нескольких переменных)
a = 5 b = 6 # printing multiple variables print(a,b) # separate the variables by the comma Print(1, 2, 3, 4, 5, 6, 7, 8)
Sysadminium
Разберём функции Python 3. Узнаем зачем они нужны, как их создавать и выполнять. Познакомимся с рекурсией, замыканиями и декораторами.
Оглавление скрыть
Функции в Python 3
Функции нужны для того чтобы описать некоторую функциональность. А затем эту функциональность можно будет использовать столько раз, сколько вам это нужно. При этом не нужно будет копировать один и тот же участок кода по нескольку раз.
Функции в Python создаются с помощью оператора def, после которого идёт название функции, круглые скобки и двоеточие. После этого, в блоке ниже описывается функциональность данной функции, такой блок называют телом функции.
Вот пример простейшей функции, которая просто выводит некий текст в консоль:
def my_func(): print('hello')
Но сама по себе функция не выполняется, её нужно вызвать. Для вызова функции, мы пишем её название и круглые скобки:
my_func() ### результат выполнения hello
Функция может не только что-то делать (высчитывать что-нибудь, выводить в консоль и так далее), но и что-то возвращать. Если функция что-то возвращает, то имя функции начинает хранить какое-то значение. Чтобы функция что-нибудь возвращала используется оператор return, например:
def my_func(): a = 2 b = 3 return(a+b)
Давайте вызовем функцию написанную выше:
my_func()
При таком вызове внешне ничего не происходит. Функция складывает значения переменных a и b, но не сообщает об этом. Зато функция возвращает результат сложения, то есть имя функции (my_func) хранит в себе значение результата сложения. Чтобы в этом убедиться, выполним:
print(my_func()) ### результат выполнения 5
То есть функция в любом случае будет что-то выполнять, но дополнительно она может и что-то возвращать.
Области видимости переменных
Локальные переменные
Возьмём предыдущую функцию:
def my_func(): a = 2 b = 3 return(a+b)
В ней есть две переменные: a и b. Эти переменные являются локальными для функции my_func. Это означает что в глобальном коде эти переменные не видны. Чтобы убедиться в этом, выполним функцию и попробуем получить значение переменной a:
my_func() print(a) ### результат выполнения NameError: name 'a' is not defined
Локальные переменные создаются в момент выполнения функции и исчезают в момент завершения её работы. И они никогда не видны в глобальной области видимости. Это позволяет создавать несколько функций с одинаковыми переменными:
def my_func(): a = 2 print(a) def my_finc2(): a = 3 print(a) my_func() my_finc2() print(a) ### результат выполнения 2 3 NameError: name 'a' is not defined
То есть первая функция вывела значение своей локальной переменной a = 2. Вторая функция вывела значение своей переменной a = 3. А из основного кода (из модуля) значение переменной a не смогло вывестись, так как там такой переменной нет.
Вложенные функции и поиск переменных
Функции в Python допускают вложенность, то есть в одной функции можно описать другую функцию. Это позволяет делать множество действий описанных ниже, но сейчас мы рассматриваем поиск переменных.
Давайте представим, что у нас есть функция, а внутри этой функции другая функция. И в обоих функциях, и в глобальном коде (модуле) есть одноимённые переменные, например:
a = 'глобальная переменная a' b = 'глобальная переменная b' с = 'глобальная переменная c' def my_func(): a = 'локальная переменная my_func a' b = 'локальная переменная my_func b' c = 'локальная переменная my_func c' def my_inner(): a = 'локальная переменная my_inner a' b = 'локальная переменная my_inner b' c = 'локальная переменная my_inner c'
Функция, когда ищет значение переменной, всегда начинает поиск в своей локальной области. А если там не находит, то ищет в локальной области родительской функции. А если и там не находит то ищет в глобальной области, то есть в основном коде программы.
Давайте изменим предыдущий код функции, чтобы функция my_func() выполняла функцию my_inner(), а функция my_inner() выводила значение переменной — ‘a‘:
a = 'глобальная переменная a' b = 'глобальная переменная b' с = 'глобальная переменная c' def my_func(): a = 'локальная переменная my_func a' b = 'локальная переменная my_func b' c = 'локальная переменная my_func c' def my_inner(): a = 'локальная переменная my_inner a' b = 'локальная переменная my_inner b' c = 'локальная переменная my_inner c' print(a) my_inner() my_func() ### результат выполнения локальная переменная my_inner a
Теперь удалим переменную ‘a‘ из функции my_inner() и повторим:
a = 'глобальная переменная a' b = 'глобальная переменная b' с = 'глобальная переменная c' def my_func(): a = 'локальная переменная my_func a' b = 'локальная переменная my_func b' c = 'локальная переменная my_func c' def my_inner(): b = 'локальная переменная my_inner b' c = 'локальная переменная my_inner c' print(a) my_inner() my_func() ### результат выполнения локальная переменная my_func a
А теперь удалим переменную ‘a‘ из функции my_func():
a = 'глобальная переменная a' b = 'глобальная переменная b' с = 'глобальная переменная c' def my_func(): b = 'локальная переменная my_func b' c = 'локальная переменная my_func c' def my_inner(): b = 'локальная переменная my_inner b' c = 'локальная переменная my_inner c' print(a) my_inner() my_func() ### результат выполнения глобальная переменная a
То есть поиск переменных идет снизу вверх, из локальной области видимости функции к родительским функциям, а дальше к глобальной области видимости. Но не наоборот, то есть из глобальной области видимости, локальные переменные функций не видны.
Не локальные переменные
А если мы хотим из вложенной функции изменить переменную в родительской функции? Для этого нужно использовать оператор nonlocal. Давайте попробуем изменить переменную ‘a‘ в функции my_func() из вложенной функции my_inner(). Дополнительно выведу значение переменной из глобального кода, который видит только свои глобальные переменные.
a = 'глобальная переменная a' b = 'глобальная переменная b' с = 'глобальная переменная c' def my_func(): a = 'локальная переменная my_func a' b = 'локальная переменная my_func b' c = 'локальная переменная my_func c' def my_inner(): nonlocal a a = 'изменённая переменная a' my_inner() print(a) my_func() print(a) # глобальный код видит только глобальные переменные ### результат выполнения изменённая переменная a глобальная переменная a
То есть, с помощью оператора nonlocal мы указали что функция my_inner() обращается не к локальной а к родительской переменной ‘a‘.
Сама функция my_func() вначале инициализирует переменные. Затем выполняет вложенную функцию my_inner(), которая изменяет переменную у родительской функции. Затем функция my_func() выводит значение переменной ‘a‘.
Дополнительно, в глобальном коде после вызова функции my_func(), выводится значение глобальной переменной ‘a‘, чтобы убедиться что оно не поменялось.
Глобальные переменные
А теперь давайте из вложенной функции my_inner() изменим глобальную переменную ‘a‘. Для этого используется оператор global, работает он схожем образом с оператором nonlocal, но указывает что обращаться мы будем не к родительской функции, а к глобальной переменной.
a = 'глобальная переменная a' b = 'глобальная переменная b' с = 'глобальная переменная c' def my_func(): a = 'локальная переменная my_func a' b = 'локальная переменная my_func b' c = 'локальная переменная my_func c' def my_inner(): global a a = 'изменённая переменная a' my_inner() print(a) my_func() print(a) # глобальный код вдит только глобальные переменные ### результат выполнения локальная переменная my_func a изменённая переменная a
Здесь из функции my_inner(), с помощью оператора global, изменяется глобальная переменная ‘a‘. А локальная переменная ‘a‘ функции my_func(), не изменяется.
Передача параметров в функцию
У функции в Python могут быть аргументы, в которые из основного кода можно передавать какие-нибудь значения. Аргументы записываются в круглых скобах при создании функции, а затем используются как локальные переменные.
Вот пример функции с аргументами:
def my_func(a, b): print(a + b)
Для передачи данных в функцию, мы должны указать параметры функции при её вызове в круглых скобках:
my_func(2, 1) my_func(3, 5) ### результат выполнения 3 8
Здесь ‘a‘ и ‘b‘ — это аргументы функции. Ну а числа, с которыми мы вызывали функцию (2, 1) и (3, 5) — называют параметрами.
Значения аргументов по умолчанию
Python позволяет задать значения по умолчанию для аргументов функции, это делается таким образом:
def my_func(a=1, b=1): print(a + b) my_func() my_func(3, 5) ### результат выполнения 2 8
То есть, если мы вызовем функцию не передав ей никаких параметров, то она возьмет значения по умолчанию. А если при вызове укажем параметры, то функция выполнит код с указанными параметрами.
Неопределённое множество параметров
Если мы не знаем сколько параметров будет передаваться в функцию, то в качестве аргумента можно использовать *args. При этом внутри функции Python локальная переменная args будет кортежем переданных параметров:
def my_func(*args): print(args) # кортеж переданных объектов print(sum(args)) # сумма объектов в кортеже for i in args: # в цикле пробегаемся по элементам кортежа print(i) my_func(3, 5, 7) ### результат выполнения (3, 5, 7) 15 3 5 7
Именованные параметры
В функцию также можно передавать именованные параметры. Для этого в момент её вызова нужно указать имя аргумента и через знак равенства значение аргумента. Вот так:
def my_func(a, b, c): print(a, b, c) my_func(a=15, c=4, b=8) # позиционные параметры ### результат выполнения 15 8 4
Неопределённое множество именованных параметров
Если мы не знаем, сколько будет передано в функцию именованных переменных, то нужно использовать агрумент **kwargs. При этом внутри функции Python можно обратится к двум разным объектам:
- kwargs — словарь переданных позиционных параметров, в виде ключ => значение;
- *kwargs — только ключи словаря.
def my_func(**kwargs): print(kwargs) # словарь позиционных параметров print(*kwargs) # только ключи словаря my_func(a=15, c=4, b=8) # позиционные параметры ### результат выполнения a c b
А так можно пробежаться по словарю переданных параметров:
def my_func(**kwargs): for i in kwargs: print(i, '=>', kwargs[i]) my_func(a=15, c=4, b=8) # позиционные параметры ### результат выполнения a => 15 c => 4 b => 8
Лямбда функции (выражения)
Лямбда функции или их ещё называют выражения — это мини функции Python, которые записываются в одну строку и для них не создаётся имени. Выражения всегда возвращают результат, и при этом не нужно использовать return.
Для их создания используется оператор lambda, дальше записываются параметры (через запятую), затем после двоеточия записывается выражение (что с этими параметрами нужно сделать).
Пример кода с lambda выражением, при этом сохраняем выражение в переменной:
# вначале создаём переменную как выражение # затем используем эту переменную my_sum = lambda x, y: x+y print(my_sum(3, 5)) ### результат выполнения 8
Пример кода без сохранения lambda выражения в переменной:
print((lambda x, y: x+y)(3, 5)) ### результат выполнения 8
Выражения используются, если функциональность функции избыточна. Мы просто хотим что-то высчитать и сразу это возвратить. При этом нам не нужно использовать эту функциональность несколько раз в коде (либо, для многократного использования, придется сохранять выражение в переменную).
Замыкания
После того как мы разобрали вложенные функции и области видимости, нам легче будет понять замыкания.
Замыкание — это когда вложенная функция использует переменную из родительской. При этом родительская функция возвращает дочернюю функцию, но без её вызова (без скобочек return inner_func а не return inner_func()).
После создания такой функции, мы сможем создавать экземпляры этой функции в коде и использовать их. Это очень похоже на экземпляры класса, хотя экземпляры класса более функциональные и логически понятнее.
Вот пример замыкания:
def main_func(value): name = value def inner_func(): print('Привет мой друг', name) return inner_func b = main_func('Миша') b() c = main_func('Саша') c() ### результат выполнения Привет мой друг Миша Привет мой друг Саша
И так, у нас есть родительская функция main_func() и дочерняя inner_func(). Родительская возвращает дочернюю (return inner_func). Дочерняя использует переменную родительской функции — name. Значит замыкание мы сделали.
Затем, в основном коде я делаю экземпляры функции: b = main_func(‘Миша’) и c = main_func(‘Саша’) и выполняю их.
То есть функция a — это функция inner_func() в которой предопределена переменная name = ‘Миша’. И подобная функция b — в которой предопределена переменная name = ‘Саша’.
Это самый простой пример, второй пример чуть посложнее:
def adder(value): def inner(a): return value + a return inner a3 = adder(3) a4 = adder(4) print(a3(1)) print(a4(3)) ### результат выполнения 4 7
Здесь у нас есть родительская функция main_func(value), и дочерняя inner_func(a). Дочерняя использует переменную от родительской — value. И родительская функция возвращает дочернюю — return inner.
Создаём экземпляры функции — a3 = adder(3) и a4 = adder(4). При этом функция a3() — это функция inner(a) с предопределённым value = 3. А функция a4() — это функция inner(a) с предопределенным value = 4.
Затем мы можем пользоваться этими функциями.
Очень хорошее видео по замыканиям, можно посмотреть здесь.
Декораторы
Чтобы усвоить эту тему нужно хорошо понять замыкания, так как декоратор это почти замыкание. Как и в замыкании, здесь присутствует вложенная функция. А родительская возвращает вложенную функцию без её вызова (без скобочек). И во вложенной функции используется переменная из родительской функции. Но в декораторе эта общая переменная — является функцией, которую мы будем декорировать.
Декораторы нужны, чтобы в вашей функции добавилась новая функциональность.
# Декоратор def header(func): def inner(): print('') func() print('
') return inner # Функция def say(): print('hello world') # Вызов функции say() ### результат выполнения hello world
Вначале мы создали функцию-декоратор header(func). Он выполняет вложенную функцию inner(), которая печатает html тег , затем выполняет функцию func(), а затем печатает закрывающий html тег .
А функция say() — просто выводит на консоль hello world. Здесь мы написали декоратор, но не использовали его.
Теперь навесим декоратор на функцию say(). Для этого просто перед созданием функции say() напишем символ ‘@’ и имя функции декоратора (@header):
# Декоратор def header(func): def inner(): print('') func() print('
') return inner # Навесили декоратор на функцию @header def say(): print('hello world') # Вызов функции say() ### результат выполнения hello world
Таким образом мы изменили функциональность функции say(). Эта функция теперь ссылается на вложенную функцию inner() в функции header(func).
А чтобы функция могла принимать аргументы мы должны прокинуть эти аргументы во вложенную функцию с помощью *args и **kwargs:
# Декоратор def header(func): def inner(*args, **kwargs): print('') func(*args, **kwargs) print('
') return inner # Навесили декоратор на функцию @header def say(n): print(n) # Вызов функции say('hello') ### результат выполнения hello
Таким образом у нас есть просто функция say(), которая выводит в терминал то, что ей передают. И мы можем её задекорировать, декоратором @header, который мы написали ранее. Тогда функция say() начнёт обрамлять вывод html тегами и .
Также, можете посмотреть видео по декораторам — здесь.
Рекурсия
Рекурсия — это когда функция вызывает саму себя, при этом у рекурсии должен быть выход. Чем больше глубина рекурсии, тем медленнее будет работать рекурсивная функция. Кстати, в Python есть ограничение на глубину вызова внутри рекурсии.
Допустим у нас есть следующая рекурсивная функция — rec(x), которая:
- выводит значение переменной x;
- вызывает саму себя, но с новыми значениями — rec(x+1); — рекурсивная функция
- выводит значение переменной x;
- и так до тех пор, пока x. — условие выхода из рекурсии
Записывается такая рекурсивная функция на языке Python следующим образом:
def rec(x): if xЕщё раз разберу как работает рекурсия на этом примере:
- Мы вызываем функцию rec(1), она проверяет что x, и выводит в консоль 1. Сохраняет состояние (x=1).
- Затем запускается rec(2). Она проверяет что x, и выводит в консоль 2. Сохраняет состояние (x=2).
- Затем запускается rec(3). Она проверяет что x, и выводит в консоль 3. Сохраняет состояние (x=3).
- Затем запускается rec(4). Проверяет что x, и так как условие не выполняется то функция завершает свою работу.
- Продолжает работать предыдущая функция, она запомнила что x=3, выводит в консоль 3. И завершает свою работу.
- Продолжает работать предыдущая функция, она запомнила что x=2, выводит в консоль 2. И завершает свою работу.
- Продолжает работать предыдущая функция, она запомнила что x=1, выводит в консоль 1. И завершает свою работу.
Пример рекурсии «нахождение чисел Фибоначчи»
Вот ещё один пример рекурсивной функции. Это поиск чисел Фибоначчи, это такие числа, которые образуются от сложения предыдущих двух чисел, начинается такой список от 0, второе число 1, а дальше начинается сложение чисел. Вот часть чисел Фибоначчи: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 и так далее.
Здесь первое число всегда равно 0, а второе число равно 1. Остальные числа легко высчитываются по формуле (предыдущее число) + (число перед предыдущим). Другими словами формула такая: (n-1) + (n-2).
Код такой функции:
def fib(n): if n==1: return 0 # первое число фибоначчи всегда 0 if n==2: return 1 # второе число фибоначчи всегда 1 return fib(n-1) + fib(n-2) print(fib(5))Мы ищем пятое число Фибоначчи. Если n=1, то это ноль. Если n=2, то это единица. Любое другое число высчитывается по формуле: fib(n-1) + fib(n-2).
В нашем примере функция работает так:
Рекурсия всегда выглядит как пробежка по дереву, вначале вглубь, затем обратно.
Но помните, чем больше вложенность, тем медленнее работают рекурсивные функции. Например, если захотите вычислить 40-ое число Фибоначчи (print(fib(40))) — то придётся немного подождать. А если 45-ое — то долго подождать.
Здесь можете посмотреть видео по рекурсии.
Итог
Если вы дошли до конца этой, довольно длинной статьи, то должны были узнать про функции и оператор def, про возвращаемые значения и оператор return. Также мы разобрали области видимости и вложенные функции, и узнали про операторы nonlocal и global. Познакомились с аргументами функции, узнали что они бывают именованные и не именнованые, узнали про аргументы *args и **kwargs. Познакомились с маленькими lambda функциями. А также узнали про замыкания, декораторы и рекурсию.
Другие статьи по Python доступны здесь.
