Как выглядит программный код python
Перейти к содержимому

Как выглядит программный код python

  • автор:

Основы языка программирования Python за 10 минут

Python Logo

На сайте Poromenos’ Stuff была
опубликована статья, в которой, в сжатой форме,
рассказывают об основах языка Python. Я предлагаю вам перевод этой статьи. Перевод не дословный. Я постарался подробнее объяснить некоторые моменты, которые могут быть непонятны.

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

Основные свойства

Python не требует явного объявления переменных, является регистро-зависим (переменная var не эквивалентна переменной Var или VAR — это три разные переменные) объектно-ориентированным языком.

Синтаксис

Во первых стоит отметить интересную особенность Python. Он не содержит операторных скобок (begin..end в pascal или <..>в Си), вместо этого блоки выделяются отступами: пробелами или табуляцией, а вход в блок из операторов осуществляется двоеточием. Однострочные комментарии начинаются со знака фунта «#», многострочные — начинаются и заканчиваются тремя двойными кавычками «"""».
Чтобы присвоить значение пременной используется знак «=», а для сравнения —
«==». Для увеличения значения переменной, или добавления к строке используется оператор «+=», а для уменьшения — «-=». Все эти операции могут взаимодействовать с большинством типов, в том числе со строками. Например

Структуры данных

Python содержит такие структуры данных как списки (lists), кортежи (tuples) и словари (dictionaries). Списки — похожи на одномерные массивы (но вы можете использовать Список включающий списки — многомерный массив), кортежи — неизменяемые списки, словари — тоже списки, но индексы могут быть любого типа, а не только числовыми. "Массивы" в Python могут содержать данные любого типа, то есть в одном массиве может могут находиться числовые, строковые и другие типы данных. Массивы начинаются с индекса 0, а последний элемент можно получить по индексу -1 Вы можете присваивать переменным функции и использовать их соответственно.

Вы можете использовать часть массива, задавая первый и последний индекс через двоеточие «:». В таком случае вы получите часть массива, от первого индекса до второго не включительно. Если не указан первый элемент, то отсчет начинается с начала массива, а если не указан последний — то масив считывается до последнего элемента. Отрицательные значения определяют положение элемента с конца. Например:

Строки

Строки в Python обособляются кавычками двойными «"» или одинарными «’». Внутри двойных ковычек могут присутствовать одинарные или наоборот. К примеру строка «Он сказал ‘привет’!» будет выведена на экран как «Он сказал ‘привет’!». Если нужно использовать строку из несколько строчек, то эту строку надо начинать и заканчивать тремя двойными кавычками «"""». Вы можете подставить в шаблон строки элементы из кортежа или словаря. Знак процента «%» между строкой и кортежем, заменяет в строке символы «%s» на элемент кортежа. Словари позволяют вставлять в строку элемент под заданным индексом. Для этого надо использовать в строке конструкцию «%(индекс)s». В этом случае вместо «%(индекс)s» будет подставлено значение словаря под заданным индексом.

>>>print «Name: %s\nNumber: %s\nString: %s» % (myclass.name, 3 , 3 * "-" )
Name: Poromenos
Number: 3
String: —
strString = ""«Этот текст расположен
на нескольких строках»""

Операторы

Операторы while, if, for составляют операторы перемещения. Здесь нет аналога оператора select, так что придется обходиться if. В операторе for происходит сравнение переменной и списка. Чтобы получить список цифр до числа <number> — используйте функцию range(<number>). Вот пример использования операторов

rangelist = range ( 10 ) #Получаем список из десяти цифр (от 0 до 9)
>>> print rangelist
[ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]
for number in rangelist: #Пока переменная number (которая каждый раз увеличивается на единицу) входит в список…
# Проверяем входит ли переменная
# numbers в кортеж чисел ( 3 , 4 , 7 , 9 )
if number in ( 3 , 4 , 7 , 9 ): #Если переменная number входит в кортеж (3, 4, 7, 9).
# Операция «break» обеспечивает
# выход из цикла в любой момент
break
else :
# «continue» осуществляет «прокрутку»
# цикла. Здесь это не требуется, так как после этой операции
# в любом случае программа переходит опять к обработке цикла
continue
else :
# «else» указывать необязательно. Условие выполняется
# если цикл не был прерван при помощи «break».
pass # Ничего не делать

if rangelist[ 1 ] == 2 :
print «The second item (lists are 0-based) is 2»
elif rangelist[ 1 ] == 3 :
print «The second item (lists are 0-based) is 3»
else :
print «Dunno»

while rangelist[ 1 ] == 1 :
pass

Функции

Для объявления функции служит ключевое слово «def». Аргументы функции задаются в скобках после названия функции. Можно задавать необязательные аргументы, присваивая им значение по умолчанию. Функции могут возвращать кортежи, в таком случае надо писать возвращаемые значения через запятую. Ключевое слово «lambda» служит для объявления элементарных функций .

# arg2 и arg3 — необязательые аргументы, принимают значение объявленное по умолчни,
# если не задать им другое значение при вызове функци.
def myfunction(arg1, arg2 = 100 , arg3 = «test» ):
return arg3, arg2, arg1
#Функция вызывается со значением первого аргумента — "Argument 1", второго — по умолчанию, и третьего — "Named argument" .
>>>ret1, ret2, ret3 = myfunction( «Argument 1» , arg3 = «Named argument» )
# ret1, ret2 и ret3 принимают значения "Named argument", 100, "Argument 1" соответственно
>>> print ret1, ret2, ret3
Named argument 100 Argument 1

# Следующая запись эквивалентна def f(x): return x + 1
functionvar = lambda x: x + 1
>>> print functionvar( 1 )
2

Классы

Язык Python ограничен в множественном наследовании в классах. Внутренние переменные и внутренние методы классов начинаются с двух знаков нижнего подчеркивания «__» (например «__myprivatevar»). Мы можем также присвоить значение переменной класса извне. Пример:

class Myclass:
common = 10
def __init__( self ):
self .myvariable = 3
def myfunction( self , arg1, arg2):
return self .myvariable

# Здесь мы объявили класс Myclass. Функция __init__ вызывается автоматически при инициализации классов.
>>> classinstance = Myclass() # Мы инициализировали класс и переменная myvariable приобрела значение 3 как заявлено в методе инициализации
>>> classinstance.myfunction( 1 , 2 ) #Метод myfunction класса Myclass возвращает значение переменной myvariable
3
# Переменная common объявлена во всех классах
>>> classinstance2 = Myclass()
>>> classinstance.common
10
>>> classinstance2.common
10
# Поэтому, если мы изменим ее значение в классе Myclass изменятся
# и ее значения в объектах, инициализированных классом Myclass
>>> Myclass.common = 30
>>> classinstance.common
30
>>> classinstance2.common
30
# А здесь мы не изменяем переменную класса. Вместо этого
# мы объявляем оную в объекте и присваиваем ей новое значение
>>> classinstance.common = 10
>>> classinstance.common
10
>>> classinstance2.common
30
>>> Myclass.common = 50
# Теперь изменение переменной класса не коснется
# переменных объектов этого класса
>>> classinstance.common
10
>>> classinstance2.common
50

# Следующий класс является наследником класса Myclass
# наследуя его свойства и методы, ктому же класс может
# наследоваться из нескольких классов, в этом случае запись
# такая: class Otherclass(Myclass1, Myclass2, MyclassN)
class Otherclass(Myclass):
def __init__( self , arg1):
self .myvariable = 3
print arg1

>>> classinstance = Otherclass( «hello» )
hello
>>> classinstance.myfunction( 1 , 2 )
3
# Этот класс не имеет совйтсва test, но мы можем
# объявить такую переменную для объекта. Причем
# tэта переменная будет членом только classinstance.
>>> classinstance.test = 10
>>> classinstance.test
10

Исключения

Исключения в Python имеют структуру tryexcept [exceptionname]:

def somefunction():
try :
# Деление на ноль вызывает ошибку
10 / 0
except ZeroDivisionError :
# Но программа не "Выполняет недопустимую операцию"
# А обрабатывает блок исключения соответствующий ошибке «ZeroDivisionError»
print «Oops, invalid.»

Импорт

Внешние библиотеки можно подключить процедурой «import [libname]», где [libname] — название подключаемой библиотеки. Вы так же можете использовать команду «from [libname] import [funcname]», чтобы вы могли использовать функцию [funcname] из библиотеки [libname]

import random #Импортируем библиотеку «random»
from time import clock #И заодно функцию «clock» из библиотеки «time»

randomint = random .randint( 1 , 100 )
>>> print randomint
64

Работа с файловой системой

Python имеет много встроенных библиотек. В этом примере мы попробуем сохранить в бинарном файле структуру списка, прочитать ее и сохраним строку в текстовом файле. Для преобразования структуры данных мы будем использовать стандартную библиотеку «pickle»

import pickle
mylist = [ «This» , «is» , 4 , 13327 ]
# Откроем файл C:\binary.dat для записи. Символ «r»
# предотвращает замену специальных сиволов (таких как \n, \t, \b и др.).
myfile = file (r «C:\binary.dat» , «w» )
pickle .dump(mylist, myfile)
myfile.close()

myfile = file (r «C:\text.txt» , «w» )
myfile.write( «This is a sample string» )
myfile.close()

myfile = file (r «C:\text.txt» )
>>> print myfile.read()
‘This is a sample string’
myfile.close()

# Открываем файл для чтения
myfile = file (r «C:\binary.dat» )
loadedlist = pickle .load(myfile)
myfile.close()
>>> print loadedlist
[ ‘This’ , ‘is’ , 4 , 13327 ]

Особенности

  • Условия могут комбинироваться. 1 < a < 3 выполняется тогда, когда а больше 1, но меньше 3.
  • Используйте операцию «del» чтобы очищать переменные или элементы массива.
  • Python предлагает большие возможности для работы со списками. Вы можете использовать операторы объявлении структуры списка. Оператор for позволяет задавать элементы списка в определенной последовательности, а if — позволяет выбирать элементы по условию.
  • Глобальные переменные объявляются вне функций и могут быть прочитанны без каких либо объявлений. Но если вам необходимо изменить значение глобальной переменной из функции, то вам необходимо объявить ее в начале функции ключевым словом «global», если вы этого не сделаете, то Python объявит переменную, доступную только для этой функции.

def myfunc():
# Выводит 5
print number

def anotherfunc():
# Это вызывает исключение, поскольку глобальная апеременная
# не была вызванна из функции. Python в этом случае создает
# одноименную переменную внутри этой функции и доступную
# только для операторов этой функции.
print number
number = 3

def yetanotherfunc():
global number
# И только из этой функции значение переменной изменяется.
number = 3

Эпилог

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

4. Execution model¶

A Python program is constructed from code blocks. A block is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class definition. Each command typed interactively is a block. A script file (a file given as standard input to the interpreter or specified as a command line argument to the interpreter) is a code block. A script command (a command specified on the interpreter command line with the -c option) is a code block. A module run as a top level script (as module __main__ ) from the command line using a -m argument is also a code block. The string argument passed to the built-in functions eval() and exec() is a code block.

A code block is executed in an execution frame. A frame contains some administrative information (used for debugging) and determines where and how execution continues after the code block’s execution has completed.

4.2. Naming and binding¶

4.2.1. Binding of names¶

Names refer to objects. Names are introduced by name binding operations.

The following constructs bind names:

formal parameters to functions,

targets that are identifiers if occurring in an assignment:

after as in a with statement, except clause, except* clause, or in the as-pattern in structural pattern matching,

in a capture pattern in structural pattern matching

The import statement of the form from . import * binds all names defined in the imported module, except those beginning with an underscore. This form may only be used at the module level.

A target occurring in a del statement is also considered bound for this purpose (though the actual semantics are to unbind the name).

Each assignment or import statement occurs within a block defined by a class or function definition or at the module level (the top-level code block).

If a name is bound in a block, it is a local variable of that block, unless declared as nonlocal or global . If a name is bound at the module level, it is a global variable. (The variables of the module code block are local and global.) If a variable is used in a code block but not defined there, it is a free variable.

Each occurrence of a name in the program text refers to the binding of that name established by the following name resolution rules.

4.2.2. Resolution of names¶

A scope defines the visibility of a name within a block. If a local variable is defined in a block, its scope includes that block. If the definition occurs in a function block, the scope extends to any blocks contained within the defining one, unless a contained block introduces a different binding for the name.

When a name is used in a code block, it is resolved using the nearest enclosing scope. The set of all such scopes visible to a code block is called the block’s environment.

When a name is not found at all, a NameError exception is raised. If the current scope is a function scope, and the name refers to a local variable that has not yet been bound to a value at the point where the name is used, an UnboundLocalError exception is raised. UnboundLocalError is a subclass of NameError .

If a name binding operation occurs anywhere within a code block, all uses of the name within the block are treated as references to the current block. This can lead to errors when a name is used within a block before it is bound. This rule is subtle. Python lacks declarations and allows name binding operations to occur anywhere within a code block. The local variables of a code block can be determined by scanning the entire text of the block for name binding operations. See the FAQ entry on UnboundLocalError for examples.

If the global statement occurs within a block, all uses of the names specified in the statement refer to the bindings of those names in the top-level namespace. Names are resolved in the top-level namespace by searching the global namespace, i.e. the namespace of the module containing the code block, and the builtins namespace, the namespace of the module builtins . The global namespace is searched first. If the names are not found there, the builtins namespace is searched. The global statement must precede all uses of the listed names.

The global statement has the same scope as a name binding operation in the same block. If the nearest enclosing scope for a free variable contains a global statement, the free variable is treated as a global.

The nonlocal statement causes corresponding names to refer to previously bound variables in the nearest enclosing function scope. SyntaxError is raised at compile time if the given name does not exist in any enclosing function scope.

The namespace for a module is automatically created the first time a module is imported. The main module for a script is always called __main__ .

Class definition blocks and arguments to exec() and eval() are special in the context of name resolution. A class definition is an executable statement that may use and define names. These references follow the normal rules for name resolution with an exception that unbound local variables are looked up in the global namespace. The namespace of the class definition becomes the attribute dictionary of the class. The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods – this includes comprehensions and generator expressions since they are implemented using a function scope. This means that the following will fail:

4.2.3. Builtins and restricted execution¶

CPython implementation detail: Users should not touch __builtins__ ; it is strictly an implementation detail. Users wanting to override values in the builtins namespace should import the builtins module and modify its attributes appropriately.

The builtins namespace associated with the execution of a code block is actually found by looking up the name __builtins__ in its global namespace; this should be a dictionary or a module (in the latter case the module’s dictionary is used). By default, when in the __main__ module, __builtins__ is the built-in module builtins ; when in any other module, __builtins__ is an alias for the dictionary of the builtins module itself.

4.2.4. Interaction with dynamic features¶

Name resolution of free variables occurs at runtime, not at compile time. This means that the following code will print 42:

The eval() and exec() functions do not have access to the full environment for resolving names. Names may be resolved in the local and global namespaces of the caller. Free variables are not resolved in the nearest enclosing namespace, but in the global namespace. 1 The exec() and eval() functions have optional arguments to override the global and local namespace. If only one namespace is specified, it is used for both.

4.3. Exceptions¶

Exceptions are a means of breaking out of the normal flow of control of a code block in order to handle errors or other exceptional conditions. An exception is raised at the point where the error is detected; it may be handled by the surrounding code block or by any code block that directly or indirectly invoked the code block where the error occurred.

The Python interpreter raises an exception when it detects a run-time error (such as division by zero). A Python program can also explicitly raise an exception with the raise statement. Exception handlers are specified with the try … except statement. The finally clause of such a statement can be used to specify cleanup code which does not handle the exception, but is executed whether an exception occurred or not in the preceding code.

Python uses the “termination” model of error handling: an exception handler can find out what happened and continue execution at an outer level, but it cannot repair the cause of the error and retry the failing operation (except by re-entering the offending piece of code from the top).

When an exception is not handled at all, the interpreter terminates execution of the program, or returns to its interactive main loop. In either case, it prints a stack traceback, except when the exception is SystemExit .

Exceptions are identified by class instances. The except clause is selected depending on the class of the instance: it must reference the class of the instance or a non-virtual base class thereof. The instance can be received by the handler and can carry additional information about the exceptional condition.

Exception messages are not part of the Python API. Their contents may change from one version of Python to the next without warning and should not be relied on by code which will run under multiple versions of the interpreter.

See also the description of the try statement in section The try statement and raise statement in section The raise statement .

This limitation occurs because the code that is executed by these operations is not available at the time the module is compiled.

Глава 1. Ваша первая программа на Python

Не убегайте от проблем, не осуждайте себя и не несите своё бремя в праведном безмолвии. У вас есть проблема? Прекрасно! Это пойдёт на пользу! Радуйтесь: погрузитесь в неё и исследуйте!

Досточтимый Хенепола Гунаратана

Содержание главы

Погружение

Обычно книги о программировании начинаются с кучи скучных глав о базовых вещах и постепенно переходят к созданию чего-нибудь полезного. Давайте всё это пропустим. Вот вам готовая, работающая программа на Python. Возможно, вы ровным счётом ничего в ней не поймёте. Не беспокойтесь об этом, скоро мы разберём её строчка за строчкой. Но сначала прочитайте код и посмотрите, что вы сможете извлечь из него.

Теперь давайте запустим эту программу из командной строки. В Windows это будет выглядеть примерно так:

В Mac OS X и Linux, будет почти то же самое:

Что сейчас произошло? Вы выполнили свою первую программу на Python. Вы вызвали интерпретатор Python в командной строке и передали ему имя скрипта, который хотели выполнить. В скрипте определена функция approximate_size() , которая принимает точный размер файла в байтах и вычисляет «красивый» (но приблизительный) размер. (Возможно, вы видели его в Проводнике Windows, в Mac OS X Finder, в Nautilus, Dolphin или Thunar в Linux. Если отобразить папку с документами в виде таблицы, файловый менеджер в каждой её строке покажет иконку, название документа, размер, тип, дату последнего изменения и т. д. Если в папке есть 1093-байтовый файл с названием « TODO », файловый менеджер не покажет « TODO 1093 байта »; вместо этого он скажет что-то типа « TODO 1 КБ ». Именно это и делает функция approximate_size() .)

Посмотрите на последние строки скрипта, вы увидите два вызова print(approximate_size(аргументы)) . Это вызовы функций. Сначала вызывается approximate_size() , которой передаётся несколько аргументов, а затем возвращённое ею значение берётся и передаётся прямо в функцию print() . Функция print() встроенная, вы нигде не найдёте её явного объявления. Её можно только использовать, где угодно и когда угодно. (Есть множество встроенных функций, и ещё больше функций, которые выделены в отдельные модули. Только терпение, непоседа.)

Итак, почему при выполнении скрипта в командной строке, всегда получается один и тот же результат? Мы ещё дойдём до этого. Но сначала давайте посмотрим на функцию approximate_size() .

1.2 Объявление функций

Когда вам нужна функция, просто объявите её.

В Python есть функции, как и в большинстве других языков, но нет ни отдельных заголовочных файлов, как в C++, ни конструкций interface/implementation , как в Паскале. Когда вам нужна функция, просто объявите её, например, так:

Объявление начинается с ключевого слова def , затем следует имя функции, а за ним аргументы в скобках. Если аргументов несколько, они разделяются запятыми.

К тому же, стоит заметить, что в объявлении функции не задаётся тип возвращаемых данных. Функции в Python не определяют тип возвращаемых ими значений; они даже не указывают, существует ли возвращаемое значение вообще. (На самом деле, любая функция в Python возвращает значение; если в функции выполняется инструкция return, она возвращает указанное в этой инструкции значение, если нет – возвращает None – специальное нулевое значение.)

В некоторых языках программирования функции (возвращающие значение) объявляются ключевым словом function , а подпрограммы (не возвращающие значений) – ключевым словом sub . В Python же подпрограмм нет. Все функции возвращают значение (даже если оно None ), и всегда объявляются ключевым словом def .

Функция approximate_size() принимает два аргумента: size и a_kilobyte_is_1024_bytes , но ни один из них не имеет типа. В Python тип переменных никогда не задаётся явно. Python вычисляет тип переменной и следит за ним самостоятельно.

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

1.2.1 Необязательные и именнованные аргументы

В Python аргументы функций могут иметь значения по умолчанию; если функция вызывается без аргумента, то он принимает своё значение по умолчанию. К тому же, аргументы можно указывать в любом порядке, задавая их имена.

Давайте ещё раз посмотрим на объявление функции approximate_size() :

Второй аргумент – a_kilobyte_is_1024_bytes – записывается со значением по умолчанию True . Это означает, что этот аргумент необязательный; можно вызвать функцию без него, а Python будет действовать так, как будто она вызвана с True в качестве второго параметра.

Теперь взглянем на последние строки скрипта:

  1. Строка 27. Функция approximate_size() вызывается с двумя аргументами. Внутри функции approximate_size() переменная a_kilobyte_is_1024_bytes будет False , поскольку False передаётся явно во втором аргументе.
  2. Строка 28. Функция approximate_size() вызывается только с одним аргументом. Но всё в порядке, потому что второй аргумент необязателен! Поскольку второй аргумент не указан, он принимает значение по умолчанию True , как определено в объявлении функции.

А ещё можно передавать значения в функцию по имени.

Перевод сообщений оболочки

Файл "<stdin>", строка 1
SyntaxError: неименованный аргумент после именованного

  1. Строка 2. Функция approximate_size() вызывается со значением 4000 в первом аргументе и False в аргументе по имени a_kilobyte_is_1024_bytes . (Он стоит на втором месте, но это не важно, как вы скоро увидите.)
  2. Строка 4. Функция approximate_size() вызывается со значением 4000 в аргументе по имени size и False в аргументе по имени a_kilobyte_is_1024_bytes . (Эти именованные аргументы стоят в том же порядке, в каком они перечислены в объявлении функции, но это тоже не важно.)
  3. Строка 6. Функция approximate_size() вызывается с False в аргументе по имени a_kilobyte_is_1024_bytes и 4000 в аргументе по имени size . (Видите? Я же говорил, что порядок не важен.)
  4. Строка 8. Этот вызов не работает, потому что за именованным аргументом следует неименованный (позиционный). Если читать список аргументов слева направо, то как только встречается именованный аргумент, все следующие за ним аргументы тоже должны быть именованными.
  5. Строка 11. Этот вызов тоже не работает, по той же причине, что и предыдущий. Удивительно? Ведь сначала передаётся 4000 в аргументе по имени size , затем, «очевидно», можно ожидать, что False станет аргументом по имени a_kilobyte_is_1024_bytes . Но в Python это не работает. Раз есть именованный аргумент, все аргументы справа от него тоже должны быть именованными.

1.3 Написание читаемого кода

Не буду растопыривать перед вами пальцы и мучить длинной лекцией о важности документирования кода. Просто знайте, что код пишется один раз, а читается многократно, и самый важный читатель вашего кода – это вы сами через полгода после написания (т. е. всё уже забыто, и вдруг понадобилось что-то починить). В Python писать читаемый код просто. Используйте это его преимущество и через полгода вы скажете мне «спасибо».

1.3.1 Строки документации

Каждая функция заслуживает хорошую документацию.

Функции в Python можно документировать, снабжая их строками документации (англ. documentation string, сокращённо docstring). В нашей программе у функции approximate_size() есть строка документации:

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

Тройные кавычки – это ещё и простой способ определить строку, содержащую одинарные (апострофы) и двойные кавычки, подобно qq/. / в Perl 5.

Всё, что находится в тройных кавычках, – это строка документации функции, описывающая, что делает эта функция. Строка документации, если она есть, должна начинать тело функции, т. е. находится на следующей строчке сразу под объявлением функции. Строго говоря, вы не обязаны писать документацию к каждой своей функции, но всегда желательно это делать. Я знаю, что вам уже все уши прожужжали про документирование кода, но Python даёт вам дополнительный стимул – строки документации доступны во время выполнения как атрибут функции.

Многие IDE для Python используют строки документации для отображения контекстной справки, и когда вы набираете название функции, её документация появляется во всплывающей подсказке. Это может быть невероятно полезно, но это всего лишь строки документации, которые вы сами пишете.

1.4 Путь поиска оператора import

Перед тем, как идти дальше, я хочу вкратце рассказать о путях поиска библиотек. Когда вы пытаетесь импортировать модуль (с помощью оператора import ), Python ищет его в нескольких местах. В частности, он ищет во всех директориях, перечисленных в sys.path . Это просто список, который можно легко просматривать и изменять при помощи стандартных списочных методов. (Вы узнаете больше о списках в главе «Встроенные типы данных».)

  1. Строка 1. Импортирование модуля sys делает доступными все его функции и атрибуты.
  2. Строка 2. sys.path – список имён директорий, определяющий текущий путь поиска. (Ваш будет выглядеть иначе, в зависимости от вашей операционной системы, от используемой версии Python и от того, куда он был установлен.) Python будет искать в этих директориях (в заданном порядке) файл с расширением « .py », имя которого совпадает с тем, что вы пытаетесь импортировать.
  3. Строка 10. Вообще-то я вас обманул; истинное положение дел немного сложнее, потому что не все модули лежат в файлах с расширением « .py ». Некоторые из них, как, например, модуль sys , являются встроенными; они впаяны в сам Python. Встроенные модули ведут себя точно так же, как обычные, но их исходный код недоступен, потому что они не были написаны на Python! (Модуль sys написан на Си.)
  4. Строка 12. Можно добавить новую директорию в путь поиска, добавив имя директории в список sys.path , во время выполнения Python, и тогда Python будет просматривать её наравне с остальными, как только вы попытаетесь импортировать модуль. Новый путь поиска будет действителен в течение всего сеанса работы Python.
  5. Строка 13. Выполнив команду sys.path.insert(0, новый_путь) , вы вставили новую директорию на первое место в список sys.path , и, следовательно, в начало пути поиска модулей. Почти всегда, именно это вам и нужно. В случае конфликта имён (например, если Python поставляется со 2-й версией некоторой библиотеки, а вы хотите использовать версию 3) этот приём гарантирует, что будут найдены и использованы ваши модули, а не те, которые идут в комплекте с Python.

1.5 Всё является объектом

Если вы вдруг пропустили, я только что сказал, что функции в Python имеют атрибуты, и эти атрибуты доступны во время выполнения. Функция, как и всё остальное в Python, является объектом.

Запустите интерактивную оболочку Python и повторите за мной:

  1. Строка 1. Первая строка импортирует программу humansize в качестве модуля – фрагмента кода, который можно использовать интерактивно или из другой Python-программы. После того, как модуль был импортирован, можно обращаться ко всем его публичным функциям, классам и атрибутам. Импорт применяется как в модулях, для доступа к функциональности других модулей, так и в интерактивной оболочке Python. Это очень важная идея, и вы ещё не раз встретите её на страницах этой книги.
  2. Строка 2. Когда вы хотите использовать функцию, определённую в импортированном модуле, нужно дописать к её имени название модуля. То есть вы не можете использовать просто approximate_size , обязательно humansize.approximate_size . Если вы использовали классы в Java, то для вас это должно быть знакомо.
  3. Строка 4. Вместо того, чтобы вызвать функцию (как вы, возможно, ожидали), вы запросили один из её атрибутов – __doc__ .

Оператор import в Python похож на require из Perl. После import в Python, вы обращаетесь к функциям модуля как модуль.функция ; после require в Perl, для обращения к функциям модуля используется имя модуль::функция .

1.5.1 Что такое объект?

В языке Python всё является объектом, и у любого объекта могут быть атрибуты и методы. Все функции имеют стандартный атрибут __doc__ , содержащий строку документации, определённую в исходном коде функции. Модуль sys – тоже объект, имеющий (кроме прочего) атрибут под названием path . И так далее.

Но мы так и не получили ответ на главный вопрос: что такое объект? Разные языки программирования определяют «объект» по-разному. В одних считается, что все объекты должны иметь атрибуты и методы. В других, что объекты могут порождать подклассы. В Python определение ещё менее чёткое. Некоторые объекты не имеют ни атрибутов, ни методов, хотя и могли бы их иметь. Не все объекты порождают подклассы. Но всё является объектом в том смысле, что может быть присвоено переменной или передано функции в качестве аргумента.

Возможно, вы встречали термин «объект первого класса» в других книгах о программировании. В Python функции – объекты первого класса. Функцию можно передать в качестве аргумента другой функции. Модули – объекты первого класса. Весь модуль целиком можно передать в качестве аргумента функции. Классы – объекты первого класса, и отдельные их экземпляры – тоже объекты первого класса.

Это очень важно, поэтому я повторю это, на случай если вы пропустили первые несколько раз: всё в Python является объектом. Строки – это объекты. Списки – объекты. Функции – объекты. Классы – объекты. Экземпляры классов – объекты. И даже модули являются объектами.

1.6 Отступы

Функции в Python не имеют ни явных указаний begin и end , ни фигурных скобок, которые бы показывали, где код функции начинается, а где заканчивается. Разделители – только двоеточие (:) и отступы самого кода.

  1. Строка 1. Блоки кода определяются по их отступам. Под «блоками кода» я подразумеваю функции, блоки if , циклы for и while и т. д. Увеличение отступа начинает блок, а уменьшение – заканчивает. Ни скобок, ни ключевых слов. Это означает, что важное значение имеют пробелы, и их количество тоже. В этом примере код функции имеет отступ в четыре пробела. Здесь не обязательно должно быть именно четыре пробела, просто их число должно быть постоянным. Первая встретившаяся строчка без отступа будет означать конец функции.
  2. Строка 2. За оператором if должен следовать блок кода. Если в результате вычисления условного выражения оно окажется истинным, то выполнится блок, выделенный отступом, в противном случае произойдёт переход к блоку else (если он есть). Обратите внимание, что нет скобок вокруг выражения.
  3. Строка 3. Эта строка находится внутри блока if . Оператор raise вызывает исключение (типа ValueError ), но только если size < 0.
  4. Строка 4. Это ещё не конец функции. Совсем пустые строки не считаются. Они могут повысить читаемость кода, но не могут служить разделителями блоков кода. Блок кода функции продолжается на следующей строке.
  5. Строка 6. Оператор цикла for тоже начинает блок кода. Блоки кода могут содержать несколько строк, а именно – столько, сколько строк имеют такую же величину отступа. Этот цикл for содержит три строки кода. Других синтаксических конструкций для описания многострочных блоков кода нет. Просто делайте отступы, и будет вам счастье!

После того, как вы переборете внутренние противоречия и проведёте пару ехидных аналогий с Фортраном, вы подружитесь с отступами и начнёте видеть их преимущества. Одно из главных преимуществ – то, что все программы на Python выглядят примерно одинаково, поскольку отступы – требование языка, а не вопрос стиля. Благодаря этому становится проще читать и понимать код на Python, написанный другими людьми.

В Python используются символы возврата каретки для разделения операторов, а также двоеточие и отступы для разделения блоков кода. В C++ и Java используются точки с запятой для разделения операторов и фигурные скобки для блоков кода.

1.7 Исключения

Исключения (англ. exceptions – нештатные, исключительные ситуации, требующие специальной обработки) используются в Python повсюду. Буквально каждый модуль в стандартной библиотеке Python использует их, да и сам Python вызывает их во многих ситуациях. Вы ещё неоднократно встретите их на страницах этой книги.

Что такое исключение? Обычно это ошибка, признак того, что что-то пошло не так. (Не все исключения являются ошибками, но пока это не важно.) В некоторых языках программирования принято возвращать код ошибки, который вы потом проверяете. В Python принято использовать исключения, которые вы обрабатываете.

Когда происходит ошибка в оболочке Python, она выводит кое-какие подробности об исключении и о том, как это случилось, и всё. Это называется необработанным исключением. Когда это исключение было вызвано, не нашлось никакого программного кода, чтобы заметить его и обработать должным образом, поэтому оно всплыло на самый верхний уровень – в оболочку Python, которая вывела немного отладочной информации и успокоилась. В оболочке это не так уж страшно, однако если это произойдёт во время работы настоящей программы, то, если исключение не будет обработано, вся программа с грохотом упадёт. Может быть это то, что вам нужно, а может, и нет.

В отличие от Java, функции в Python не содержат объявлений о том, какие исключения они могут вызывать. Вам решать, какие из возможных исключений необходимо отлавливать.

Результат исключения – это не всегда полный крах программы. Исключения можно обработать. Иногда исключения возникают из-за настоящих ошибок в вашем коде (например, доступ к переменной, которая не существует), но порой исключение – это нечто, что вы можете предвидеть. Если вы открываете файл, он может не существовать. Если вы импортируете модуль, он может быть не установлен. Если вы подключаетесь к базе данных, она может быть недоступна или у вас может быть недостаточно прав для доступа к ней. Если вы знаете, что какая-то строка кода может вызвать исключение, то его следует обработать с помощью блока try. except .

Python использует для обработки исключений блоки try. except , а для их генерации – оператор raise . Java и C++ используют для обработки исключений блоки try. catch , а для их генерации – оператор throw .

Функция approximate_size() вызывает исключение в двух разных случаях: если переданный ей размер ( size ) больше, чем функция может обработать, или если он меньше нуля.

Синтаксис вызова исключений достаточно прост. Надо написать оператор raise , за ним название исключения и опционально, поясняющую строку для отладки. Синтаксис напоминает вызов функции. (На самом деле, исключения реализованы как классы, и оператор raise просто создаёт экземпляр класса ValueError и передаёт в его метод инициализации строку ' число должно быть неотрицательным '. Но мы забегаем вперёд!)

Нет необходимости обрабатывать исключение в той функции, которая его вызвала. Если одна функция не обработает его, исключение передаётся в функцию, вызвавшую эту, затем в функцию, вызвавшую вызвавшую, и т. д. «вверх по стеку». Если исключение нигде не будет обработано, то программа упадёт, а Python выведет «раскрутку стека» (англ. traceback) в стандартный поток ошибок – и на этом конец. Повторяю, возможно, это именно то, что вам нужно, – это зависит от того, что делает ваша программа.

1.7.1 Отлов ошибок импорта

Одно из встроенных исключений Python – ImportError (ошибка импорта), которое вызывается, если не удаётся импортировать модуль. Это может случиться по нескольким причинам, самая простая из которых – отсутствие модуля в пути поиска, оператора import . Вы можете использовать это для включения в программу опциональных возможностей. Например, библиотека chardet предоставляет возможность автоматического определения кодировки символов. Предположим, ваша программа хочет использовать эту библиотеку в том случае, если она есть, или спокойно продолжить работу, если пользователь не установил её. Можно сделать это с помощью блока try. except .

После этого можно проверять наличие модуля chardet простым if :

Другое частое применение исключения ImportError – выбор из двух модулей, предоставляющих одинаковый интерфейс (API), причём применение одного из них предпочтительнее другого (может, он быстрее работает или требует меньше памяти). Для этого можно попытаться импортировать сначала один модуль, и если это не удалось , то импортировать другой. К примеру, в главе XML рассказывается о двух модулях, реализующих один и тот же API, так называемый ElementTree API . Первый – lxml – сторонний модуль, который необходимо скачивать и устанавливать самостоятельно. Второй – xml.etree.ElementTree – медленнее, но входит в стандартную библиотеку Python 3.

При выполнении этого блока try. except будет импортирован один из двух модулей под именем etree . Поскольку оба модуля реализуют один и тот же API, то в последующем коде нет необходимости проверять, какой из этих модулей был импортирован. И раз импортированный модуль в любом случае именуется как etree , то не придётся вставлять лишние if для обращения к разноимённым модулям.

1.8 Несвязанные переменные

Взглянем ещё раз на вот эту строку функции approximate_size() :

Мы нигде не объявляли переменную multiple (множитель), мы только присвоили ей значение. Всё в порядке, Python позволяет так делать. Что он не позволит сделать, так это обратиться к переменной, которой не было присвоено значение. Если попытаться так сделать, возникнет исключение NameError (ошибка в имени).

Перевод сообщения оболочки

Раскрутка стека (список последних вызовов):
Файл "<stdin>", строка 1, <модуль>
NameError: имя 'x' не определено

Однажды вы скажете Python «спасибо» за это.

1.9 Всё чувствительно к регистру

Все имена в Python чувствительны к регистру – имена переменных, функций, классов, модулей, исключений. Всё, что можно прочитать, записать, вызвать, создать или импортировать, чувствительно к регистру.

Перевод сообщений оболочки

Раскрутка стека (список последних вызовов):
Файл "<stdin>", строка 1, <модуль>
NameError: имя '<имя>' не определено

1.10 Запуск скриптов

В Python всё является объектом.

Модули Python – это объекты, имеющие несколько полезных атрибутов. И это обстоятельство можно использовать для простого тестирования модулей, при их написании, путём включения специального блока кода, который будет выполняться при запуске файла из командной строки. Взгляните на последние строки humansize.py :

Как и в C, в Python оператор == используется для проверки на равенство, а оператор = используется для присваивания. Но в отличие от C, Python не поддерживает присваивание внутри другого выражения, поэтому у вас не получится случайно присвоить значение вместо проверки на равенство.

Итак, что же делает этот блок if особенным? У всех модулей, как у объектов, есть встроенный атрибут __name__ (имя). И значение этого атрибута зависит от того, как модуль используется. Если модуль импортируется, то __name__ принимает значение равное имени файла модуля, без расширения и пути к каталогу.

Но модуль можно запустить и напрямую, как самостоятельную программу, в этом случае __name__ примет специальное значение по умолчанию, __main__ . Python вычислит значение условного выражения в операторе if , определит его истинность, и выполнит блок кода if . В данном случае, будут напечатаны два значения.

Python Code Examples – Sample Script Coding Tutorial for Beginners

Python Code Examples – Sample Script Coding Tutorial for Beginners

Hi! Welcome. If you are learning Python, then this article is for you. You will find a thorough description of Python syntax and lots of code examples to guide you during your coding journey.

What we will cover:

Are you ready? Let’s begin! ��

�� Tip: throughout this article, I will use <> to indicate that this part of the syntax will be replaced by the element described by the text. For example, <var> means that this will be replaced by a variable when we write the code.

�� Variable Definitions in Python

The most basic building-block of any programming language is the concept of a variable, a name and place in memory that we reserve for a value.

In Python, we use this syntax to create a variable and assign a value to this variable:

If the name of a variable has more than one word, then the Style Guide for Python Code recommends separating words with an underscore «as necessary to improve readability.»

�� Tip: The Style Guide for Python Code (PEP 8) has great suggestions that you should follow to write clean Python code.

�� Hello, World! Program in Python

Before we start diving into the data types and data structures that you can use in Python, let’s see how you can write your first Python program.

You just need to call the print() function and write «Hello, World!» within parentheses:

You will see this message after running the program:

�� Tip: Writing a «Hello, World!» program is a tradition in the developer community. Most developers start learning how to code by writing this program.

Great. You just wrote your first Python program. Now let’s start learning about the data types and built-in data structures that you can use in Python.

�� Data Types and Built-in Data Structures in Python

We have several basic data types and built-in data structures that we can work with in our programs. Each one has its own particular applications. Let’s see them in detail.

Numeric Data Types in Python: Integers, Floats, and Complex

These are the numeric types that you can work with in Python:

Integers

Integers are numbers without decimals. You can check if a number is an integer with the type() function. If the output is <class ‘int’> , then the number is an integer.

Floats

Floats are numbers with decimals. You can detect them visually by locating the decimal point. If we call type() to check the data type of these values, we will see this as the output:

Here we have some examples:

Complex

Complex numbers have a real part and an imaginary part denoted with j . You can create complex numbers in Python with complex() . The first argument will be the real part and the second argument will be the imaginary part.

These are some examples:

Strings in Python

Strings incredibly helpful in Python. They contain a sequence of characters and they are usually used to represent text in the code.

We can use both single quotes » or double quotes «» to define a string. They are both valid and equivalent, but you should choose one of them and use it consistently throughout the program.

�� Tip: Yes! You used a string when you wrote the «Hello, World!» program. Whenever you see a value surrounded by single or double quotes in Python, that is a string.

Strings can contain any character that we can type in our keyboard, including numbers, symbols, and other special characters.

�� Tip: Spaces are also counted as characters in a string.

Quotes Within Strings

If we define a string with double quotes «» , then we can use single quotes within the string. For example:

If we define a string with single quotes » , then we can use double quotes within the string. For example:

String Indexing

We can use indices to access the characters of a string in our Python program. An index is an integer that represents a specific position in the string. They are associated to the character at that position.

This is a diagram of the string «Hello» :

�� Tip: Indices start from 0 and they are incremented by 1 for each character to the right.

We can also use negative indices to access these characters:

�� Tip: we commonly use -1 to access the last character of a string.

String Slicing

We may also need to get a slice of a string or a subset of its characters. We can do so with string slicing.

This is the general syntax:

start is the index of the first character that will be included in the slice. By default, it’s 0 .

  • stop is the index of the last character in the slice (this character will not be included). By default, it is the last character in the string (if we omit this value, the last character will also be included).
  • step is how much we are going to add to the current index to reach the next index.

We can specify two parameters to use the default value of step , which is 1 . This will include all the characters between start and stop (not inclusive):

�� Tip: Notice that if the value of a parameter goes beyond the valid range of indices, the slice will still be presented. This is how the creators of Python implemented this feature of string slicing.

If we customize the step , we will «jump» from one index to the next according to this value.

We can also use a negative step to go from right to left:

And we can omit a parameter to use its default value. We just have to include the corresponding colon ( : ) if we omit start , stop , or both:

�� Tip: The last example is one of the most common ways to reverse a string.

f-Strings

In Python 3.6 and more recent versions, we can use a type of string called f-string that helps us format our strings much more easily.

To define an f-string, we just add an f before the single or double quotes. Then, within the string, we surround the variables or expressions with curly braces <> . This replaces their value in the string when we run the program.

Here we have an example where we calculate the value of an expression and replace the result in the string:

The values are replaced in the output:

We can also call methods within the curly braces and the value returned will be replaced in the string when we run the program:

String Methods

Strings have methods, which represent common functionality that has been implemented by Python developers, so we can use it in our programs directly. They are very helpful to perform common operations.

This is the general syntax to call a string method:

To learn more about Python methods, I would recommend reading this article from the Python documentation.

�� Tip: All string methods return copies of the string. They do not modify the string because strings are immutable in Python.

Booleans in Python

Boolean values are True and False in Python. They must start with an uppercase letter to be recognized as a boolean value.

If we write them in lowercase, we will get an error:

Lists in Python

Now that we’ve covered the basic data types in Python, let’s start covering the built-in data structures. First, we have lists.

To define a list, we use square brackets [] with the elements separated by a comma.

�� Tip: It’s recommended to add a space after each comma to make the code more readable.

For example, here we have examples of lists:

Lists can contain values of different data types, so this would be a valid list in Python:

We can also assign a list to a variable:

Nested Lists

Lists can contain values of any data type, even other lists. These inner lists are called nested lists.

In this example, [1, 2, 3] and [4, 5, 6] are nested lists.

Here we have other valid examples:

We can access the nested lists using their corresponding index:

Nested lists could be used to represent, for example, the structure of a simple 2D game board where each number could represent a different element or tile:

List Length

We can use the len() function to get the length of a list (the number of elements it contains).

Update a Value in a List

We can update the value at a particular index with this syntax:

Add a Value to a List

We can add a new value to the end of a list with the .append() method.

Remove a Value from a List

We can remove a value from a list with the .remove() method.

�� Tip: This will only remove the first occurrence of the element. For example, if we try to remove the number 3 from a list that has two number 3s, the second number will not be removed:

List Indexing

We can index a list just like we index strings, with indices that start from 0 :

List Slicing

We can also get a slice of a list using the same syntax that we used with strings and we can omit the parameters to use their default values. Now, instead of adding characters to the slice, we will be adding the elements of the list.

List Methods

Python also has list methods already implemented to help us perform common list operations. Here are some examples of the most commonly used list methods:

To learn more about list methods, I would recommend reading this article from the Python documentation.

Tuples in Python

To define a tuple in Python, we use parentheses () and separate the elements with a comma. It is recommended to add a space after each comma to make the code more readable.

We can assign tuples to variables:

Tuple Indexing

We can access each element of a tuple with its corresponding index:

We can also use negative indices:

Tuple Length

To find the length of a tuple, we use the len() function, passing the tuple as argument:

Nested Tuples

Tuples can contain values of any data type, even lists and other tuples. These inner tuples are called nested tuples.

In this example, we have a nested tuple (4, 5, 6) and a list. You can access these nested data structures with their corresponding index.

Tuple Slicing

We can slice a tuple just like we sliced lists and strings. The same principle and rules apply.

This is the general syntax:

Tuple Methods

There are two built-in tuple methods in Python:

�� Tip: tuples are immutable. They cannot be modified, so we can’t add, update, or remove elements from the tuple. If we need to do so, then we need to create a new copy of the tuple.

Tuple Assignment

In Python, we have a really cool feature called Tuple Assignment. With this type of assignment, we can assign values to multiple variables on the same line.

The values are assigned to their corresponding variables in the order that they appear. For example, in a, b = 1, 2 the value 1 is assigned to the variable a and the value 2 is assigned to the variable b .

�� Tip: Tuple assignment is commonly used to swap the values of two variables:

Dictionaries in Python

Now let’s start diving into dictionaries. This built-in data structure lets us create pairs of values where one value is associated with another one.

To define a dictionary in Python, we use curly brackets <> with the key-value pairs separated by a comma.

The key is separated from the value with a colon : , like this:

You can assign the dictionary to a variable:

The keys of a dictionary must be of an immutable data type. For example, they can be strings, numbers, or tuples but not lists since lists are mutable.

  • Strings:
  • Numbers:
  • Tuples:

The values of a dictionary can be of any data type, so we can assign strings, numbers, lists, tuple, sets, and even other dictionaries as the values. Here we have some examples:

Dictionary Length

To get the number of key-value pairs, we use the len() function:

Get a Value in a Dictionary

To get a value in a dictionary, we use its key with this syntax:

This expression will be replaced by the value that corresponds to the key.

The output is the value associated to «a» :

Update a Value in a Dictionary

To update the value associated with an existing key, we use the same syntax but now we add an assignment operator and the value:

Now the dictionary is:

Add a Key-Value Pair to a Dictionary

The keys of a dictionary have to be unique. To add a new key-value pair we use the same syntax that we use to update a value, but now the key has to be new.

Now the dictionary has a new key-value pair:

Delete a Key-Value Pair in a Dictionary

To delete a key-value pair, we use the del statement:

Now the dictionary is:

Dictionary Methods

These are some examples of the most commonly used dictionary methods:

To learn more about dictionary methods, I recommend reading this article from the documentation.

�� Python Operators

Great. Now you know the syntax of the basic data types and built-in data structures in Python, so let’s start diving into operators in Python. They are essential to perform operations and to form expressions.

Arithmetic Operators in Python

These operators are:

Addition: +

�� Tip: The last two examples are curious, right? This operator behaves differently based on the data type of the operands.

When they are strings, this operator concatenates the strings and when they are Boolean values, it performs a particular operation.

In Python, True is equivalent to 1 and False is equivalent to 0 . This is why the result is 1 + 0 = 1

Subtraction: —
Multiplication: *

�� Tip: you can «multiply» a string by an integer to repeat the string a given number of times.

Exponentiation: **
Division: /

�� Tip: this operator returns a float as the result, even if the decimal part is .0

If you try to divide by 0 , you will get a ZeroDivisionError :

Integer Division: //

This operator returns an integer if the operands are integers. If they are floats, the result will be a float with .0 as the decimal part because it truncates the decimal part.

Modulo: %
Comparison Operators

These operators are:

  • Greater than: >
  • Greater than or equal to: >=
  • Less than: <
  • Less than or equal to: <=
  • Equal to: ==
  • Not Equal to: !=

These comparison operators make expressions that evaluate to either True or False . Here we have are some examples:

We can also use them to compare strings based on their alphabetical order:

We typically use them to compare the values of two or more variables:

�� Tip: notice that the comparison operator is == while the assignment operator is = . Their effect is different. == returns True or False while = assigns a value to a variable.

Comparison Operator Chaining

In Python, we can use something called «comparison operator chaining» in which we chain the comparison operators to make more than one comparison more concisely.

For example, this checks if a is less than b and if b is less than c :

Here we have some examples:

Logical Operators

There are three logical operators in Python: and , or , and not . Each one of these operators has its own truth table and they are essential to work with conditionals.

The and operator:

The or operator:

The not operator:

These operator are used to form more complex expressions that combine different operators and variables.

Assignment Operators

Assignment operators are used to assign a value to a variable.

  • The = operator assigns the value to the variable.
  • The other operators perform an operation with the current value of the variable and the new value and assigns the result to the same variable.

�� Tips: these operators perform bitwise operations before assigning the result to the variable: &= , |= , ^= , >>= , <<= .

Membership Operators

You can check if an element is in a sequence or not with the operators: in and not in . The result will be either True or False .

We typically use them with variables that store sequences, like in this example:

�� Conditionals in Python

Now let’s see how we can write conditionals to make certain parts of our code run (or not) based on whether a condition is True or False .

if statements in Python

This is the syntax of a basic if statement:

If the condition is True , the code will run. Else, if it’s False , the code will not run.

�� Tip: there is a colon ( : ) at the end of the first line and the code is indented. This is essential in Python to make the code belong to the conditional.

Here we have some examples:

False Condition

The condition is x > 9 and the code is print(«Hello, World!») .

In this case, the condition is False , so there is no output.

True Condition

Here we have another example. Now the condition is True :

Code After the Conditional

Here we have an example with code that runs after the conditional has been completed. Notice that the last line is not indented, which means that it doesn’t belong to the conditional.

In this example, the condition x > 9 is False , so the first print statement doesn’t run but the last print statement runs because it is not part of the conditional, so the output is:

However, if the condition is True , like in this example:

The output will be:

Examples of Conditionals

This is another example of a conditional:

In this case, the output will be:

But if we change the value of favorite_season :

There will be no output because the condition will be False .

if/else statements in Python

We can add an else clause to the conditional if we need to specify what should happen when the condition is False .

This is the general syntax:

�� Tip: notice that the two code blocks are indented ( if and else ). This is essential for Python to be able to differentiate between the code that belongs to the main program and the code that belongs to the conditional.

Let’s see an example with the else clause:

True Condition

When the condition of the if clause is True , this clause runs. The else clause doesn’t run.

False Condition

Now the else clause runs because the condition is False .

Now the output is:

if/elif/else statements in Python

To customize our conditionals even further, we can add one or more elif clauses to check and handle multiple conditions. Only the code of the first condition that evaluates to True will run.

�� Tip: elif has to be written after if and before else .

First Condition True

We have two conditions x < 9 and x < 15 . Only the code block from the first condition that is True from top to bottom will be executed.

In this case, the output is:

Because the first condition is True : x < 9 .

Second Condition True

If the first condition is False , then the second condition will be checked.

In this example, the first condition x < 9 is False but the second condition x < 15 is True , so the code that belongs to this clause will run.

All Conditions are False

If all conditions all False , then the else clause will run:

The output will be:

Multiple elif Clauses

We can add as many elif clauses as needed. This is an example of a conditional with two elif clauses:

Each condition will be checked and only the code block of the first condition that evaluates to True will run. If none of them are True , the else clause will run.

�� For Loops in Python

Now you know how to write conditionals in Python, so let’s start diving into loops. For loops are amazing programming structures that you can use to repeat a code block a specific number of times.

This is the basic syntax to write a for loop in Python:

The iterable can be a list, tuple, dictionary, string, the sequence returned by range, a file, or any other type of iterable in Python. We will start with range() .

The range() function in Python

This function returns a sequence of integers that we can use to determine how many iterations (repetitions) of the loop will be completed. The loop will complete one iteration per integer.

�� Tip: Each integer is assigned to the loop variable one at a time per iteration.

This is the general syntax to write a for loop with range() :

As you can see, the range function has three parameters:

  • start : where the sequence of integers will start. By default, it’s 0 .
  • stop : where the sequence of integers will stop (without including this value).
  • step : the value that will be added to each element to get the next element in the sequence. By default, it’s 1 .

You can pass 1, 2, or 3 arguments to range() :

  • With 1 argument, the value is assigned to the stop parameter and the default values for the other two parameters are used.
  • With 2 arguments, the values are assigned to the start and stop parameters and the default value for step is used.
  • With 3 arguments, the values are assigned to the start , stop , and step parameters (in order).

Here we have some examples with one parameter:

�� Tip: the loop variable is updated automatically.

In the example below, we repeat a string as many times as indicated by the value of the loop variable:

We can also use for loops with built-in data structures such as lists:

�� Tip: when you use range(len(<seq>)) , you get a sequence of numbers that goes from 0 up to len(<seq>)-1 . This represents the sequence of valid indices.

These are some examples with two parameters:

Code:

Code:

Code:

Now the list is: [‘a’, ‘b’, ‘cc’, ‘d’]

These are some examples with three parameters:

Code:

Code:

How to Iterate over Iterables in Python

We can iterate directly over iterables such as lists, tuples, dictionaries, strings, and files using for loops. We will get each one of their elements one at a time per iteration. This is very helpful to work with them directly.

Let’s see some examples:

Iterate Over a String

If we iterate over a string, its characters will be assigned to the loop variable one by one (including spaces and symbols).

We can also iterate over modified copies of the string by calling a string method where we specify the iterable in the for loop. This will assign the copy of the string as the iterable that will be used for the iterations, like this:

Iterate Over Lists and Tuples

Code:

Iterate Over the Keys, Values, and Key-Value Pairs of Dictionaries

We can iterate over the keys, values, and key-value pairs of a dictionary by calling specific dictionary methods. Let’s see how.

To iterate over the keys, we write:

We just write the name of the variable that stores the dictionary as the iterable.

�� Tip: you can also write <dictionary_variable>.keys() but writing the name of the variable directly is more concise and it works exactly the same.

�� Tip: you can assign any valid name to the loop variable.

To iterate over the values, we use:

To iterate over the key-value pairs, we use:

�� Tip: we are defining two loop variables because we want to assign the key and the value to variables that we can use in the loop.

If we define only one loop variable, this variable will contain a tuple with the key-value pair:

Break and Continue in Python

Now you know how to iterate over sequences in Python. We also have loop control statements to customize what happens when the loop runs: break and continue .

The Break Statement

The break statement is used to stop the loop immediately.

When a break statement is found, the loop stops and the program returns to its normal execution beyond the loop.

In the example below, we stop the loop when an even element is found.

The Continue Statement

The continue statement is used to skip the rest of the current iteration.

When it is found during the execution of the loop, the current iteration stops and a new one begins with the updated value of the loop variable.

In the example below, we skip the current iteration if the element is even and we only print the value if the element is odd:

The zip() function in Python

zip() is an amazing built-in function that we can use in Python to iterate over multiple sequences at once, getting their corresponding elements in each iteration.

We just need to pass the sequences as arguments to the zip() function and use this result in the loop.

The enumerate() Function in Python

You can also keep track of a counter while the loop runs with the enum() function. It is commonly used to iterate over a sequence and get the corresponding index.

�� Tip: By default, the counter starts at 0 .

If you start the counter from 0 , you can use the index and the current value in the same iteration to modify the sequence:

You can start the counter from a different number by passing a second argument to enumerate() :

The else Clause

For loops also have an else clause. You can add this clause to the loop if you want to run a specific block of code when the loop completes all its iterations without finding the break statement.

�� Tip: if break is found, the else clause doesn’t run and if break is not found, the else clause runs.

In the example below, we try to find an element greater than 6 in the list. That element is not found, so break doesn’t run and the else clause runs.

However, if the break statement runs, the else clause doesn’t run. We can see this in the example below:

�� While Loops in Python

While loops are similar to for loops in that they let us repeat a block of code. The difference is that while loops run while a condition is True .

In a while loop, we define the condition, not the number of iterations. The loop stops when the condition is False .

This is the general syntax of a while loop:

�� Tip: in while loops, you must update the variables that are part of the condition to make sure that the condition will eventually become False .

Break and Continue

We can also use break and continue with while loops and they both work exactly the same:

  • break stops the while loop immediately.
  • continue stops the current iteration and starts the next one.
The else Clause

We can also add an else clause to a while loop. If break is found, the else clause doesn’t run but if the break statement is not found, the else clause runs.

In the example below, the break statement is not found because none of the numbers are even before the condition becomes False , so the else clause runs.

This is the output:

But in this version of the example, the break statement is found and the else clause doesn’t run:

Infinite While Loops

When we write and work with while loops, we can have something called an «infinite loop.» If the condition is never False , the loop will never stop without external intervention.

This usually happens when the variables in the condition are not updated properly during the execution of the loop.

�� Tip: you must make the necessary updates to these variables to make sure that the condition will eventually evaluate to False .

�� Tip: to stop this process, type CTRL + C . You should see a KeyboardInterrupt message.

�� Nested Loops in Python

We can write for loops within for loops and while loops within while loops. These inner loops are called nested loops.

�� Tip: the inner loop runs for each iteration of the outer loop.

Nested For Loops in Python

If we add print statements, we can see what is happening behind the scenes:

The inner loop completes two iterations per iteration of the outer loop. The loop variables are updated when a new iteration starts.

This is another example:

Nested While Loops in Python

Here we have an example of nested while loops. In this case, we have to update the variables that are part of each condition to guarantee that the loops will stop.

�� Tip: we can also have for loops within while loops and while loops within for loops.

�� Functions in Python

In Python, we can define functions to make our code reusable, more readable, and organized. This is the basic syntax of a Python function:

�� Tip: a function can have zero, one, or multiple parameters.

Function with No Parameters in Python

A function with no parameters has an empty pair of parentheses after its name in the function definition. For example:

This is the output when we call the function:

�� Tip: You have to write an empty pair of parentheses after the name of the function to call it.

Function with One Parameter in Python

A function with one or more parameters has a list of parameters surrounded by parentheses after its name in the function definition:

When we call the function, we just need to pass one value as argument and that value will be replaced where we use the parameter in the function definition:

Here we have another example – a function that prints a pattern made with asterisks. You have to specify how many rows you want to print:

You can see the different outputs for different values of num_rows :

Functions with Two or More Parameters in Python

To define two or more parameters, we just separate them with a comma:

Now when we call the function, we must pass two arguments:

We can adapt the function that we just saw with one parameter to work with two parameters and print a pattern with a customized character:

You can see the output with the customized character is that we call the function passing the two arguments:

How to Return a Value in Python

Awesome. Now you know how to define a function, so let’s see how you can work with return statements.

We will often need to return a value from a function. We can do this with the return statement in Python. We just need to write this in the function definition:

�� Tip: the function stops immediately when return is found and the value is returned.

Here we have an example:

Now we can call the function and assign the result to a variable because the result is returned by the function:

We can also use return with a conditional to return a value based on whether a condition is True or False .

In this example, the function returns the first even element found in the sequence:

If we call the function, we can see the expected results:

�� Tip: if a function doesn’t have a return statement or doesn’t find one during its execution, it returns None by default.

The Style Guide for Python Code recommends using return statements consistently. It mentions that we should:

Default Arguments in Python

We can assign default arguments for the parameters of our function. To do this, we just need to write <parameter>=<value> in the list of parameters.

�� Tip: The Style Guide for Python Code mentions that we shouldn’t «use spaces around the = sign when used to indicate a keyword argument.»

In this example, we assign the default value 5 to the parameter b . If we omit this value when we call the function, the default value will be used.

If we call the function without this argument, you can see the output:

We confirm that the default argument 5 was used in the operation.

But we can also assign a custom value for b by passing a second argument:

�� Tip: parameters with default arguments have to be defined at the end of the list of parameters. Else, you will see this error: SyntaxError: non-default argument follows default argument .

Here we have another example with the function that we wrote to print a pattern. We assign the default value «*» to the char parameter.

Now we have the option to use the default value or customize it:

�� Recursion in Python

A recursive function is a function that calls itself. These functions have a base case that stops the recursive process and a recursive case that continues the recursive process by making another recursive call.

Here we have some examples in Python:

Recursive Factorial Function The Fibonacci Function Find a Power Recursively

�� Exception Handling in Python

An error or unexpected event that that occurs while a program is running is called an exception. Thanks to the elements that we will see in just a moment, we can avoid terminating the program abruptly when this occurs.

Let’s see the types of exceptions in Python and how we can handle them.

Common Exceptions in Python

This is a list of common exceptions in Python and why they occur:

  • ZeroDivisionError: raised when the second argument of a division or modulo operation is zero.
  • IndexError: raised when we try to use an invalid index to access an element of a sequence.
  • KeyError: raised when we try to access a key-value pair that doesn’t exist because the key is not in the dictionary.
  • NameError: raised when we use a variable that has not been defined previously.
  • RecursionError: raised when the interpreter detects that the maximum recursion depth is exceeded. This usually occurs when the process never reaches the base case.

In the example below, we will get a RecursionError . The factorial function is implemented recursively but the argument passed to the recursive call is n instead of n-1 . Unless the value is already 0 or 1 , the base case will not be reached because the argument is not being decremented, so the process will continue and we will get this error.

�� Tip: to learn more about these exceptions, I recommend reading this article from the documentation.

try / except in Python

We can use try/except in Python to catch the exceptions when they occur and handle them appropriately. This way, the program can terminate appropriately or even recover from the exception.

This is the basic syntax:

For example, if we take user input to access an element in a list, the input might not be a valid index, so an exception could be raised:

If we enter an invalid value like 15, the output will be:

Because the except clause runs. However, if the value is valid, the code in try will run as expected.

Here we have another example:

How to Catch a Specific Type of Exception in Python

Instead of catching and handling all possible exceptions that could occur in the try clause, we could catch and handle a specific type of exception. We just need to specify the type of the exception after the except keyword:

How to Assign a Name to the Exception Object in Python

We can specify a name for the exception object by assigning it to a variable that we can use in the except clause. This will let us access its description and attributes.

We only need to add as <name> , like this:

This is the output if we enter 15 as the index:

This is another example:

This is the output if we enter the value 0 for b :

try / except / else in Python

We can add an else clause to this structure after except if we want to choose what happens when no exceptions occur during the execution of the try clause:

If we enter the values 5 and 0 for a and b respectively, the output is:

But if both values are valid, for example 5 and 4 for a and b respectively, the else clause runs after try is completed and we see:

try / except / else / finally in Python

We can also add a finally clause if we need to run code that should always run, even if an exception is raised in try .

If both values are valid, the output is the result of the division and:

And if an exception is raised because b is 0 , we see:

The finally clause always runs.

�� Tip: this clause can be used, for example, to close files even if the code throws an exception.

�� Object-Oriented Programming in Python

In Object-Oriented Programming (OOP), we define classes that act as blueprints to create objects in Python with attributes and methods (functionality associated with the objects).

This is a general syntax to define a class:

�� Tip: self refers to an instance of the class (an object created with the class blueprint).

As you can see, a class can have many different elements so let’s analyze them in detail:

Class Header

The first line of the class definition has the class keyword and the name of the class:

�� Tip: If the class inherits attributes and methods from another class, we will see the name of the class within parentheses:

In Python, we write class name in Upper Camel Case (also known as Pascal Case), in which each word starts with an uppercase letter. For example: FamilyMember

__init__ and instance attributes

We are going to use the class to create object in Python, just like we build real houses from blueprints.

The objects will have attributes that we define in the class. Usually, we initialize these attributes in __init__ . This is a method that runs when we create an instance of the class.

This is the general syntax:

We specify as many parameters as needed to customize the values of the attributes of the object that will be created.

Here is an example of a Dog class with this method:

�� Tip: notice the double leading and trailing underscore in the name __init__ .

How to Create an Instance

To create an instance of Dog , we need to specify the name and age of the dog instance to assign these values to the attributes:

Great. Now we have our instance ready to be used in the program.

Some classes will not require any arguments to create an instance. In that case, we just write empty parentheses. For example:

To create an instance:

�� Tip: self is like a parameter that acts «behind the scenes», so even if you see it in the method definition, you shouldn’t consider it when you pass the arguments.

Default Arguments

We can also assign default values for the attributes and give the option to the user if they would like to customize the value.

In this case, we would write <attribute>=<value> in the list of parameters.

This is an example:

Now we can create a Circle instance with the default value for the radius by omitting the value or customize it by passing a value:

How to Get an Instance Attribute

To access an instance attribute, we use this syntax:

How to Update an Instance Attribute

To update an instance attribute, we use this syntax:

How to Remove an Instance Attribute

To remove an instance attribute, we use this syntax:

How to Delete an Instance

Similarly, we can delete an instance using del :

Public vs. Non-Public Attributes in Python

In Python, we don’t have access modifiers to functionally restrict access to the instance attributes, so we rely on naming conventions to specify this.

For example, by adding a leading underscore, we can signal to other developers that an attribute is meant to be non-public.

The Python documentation mentions:

Use one leading underscore only for non-public methods and instance variables.

Always decide whether a class’s methods and instance variables (collectively: «attributes») should be public or non-public. If in doubt, choose non-public; it’s easier to make it public later than to make a public attribute non-public.

Non-public attributes are those that are not intended to be used by third parties; you make no guarantees that non-public attributes won’t change or even be removed. — source

However, as the documentation also mentions:

�� Tip: technically, we can still access and modify the attribute if we add the leading underscore to its name, but we shouldn’t.

Class Attributes in Python

Class attributes are shared by all instances of the class. They all have access to this attribute and they will also be affected by any changes made to these attributes.

�� Tip: usually, they are written before the __init__ method.

How to Get a Class Attribute

To get the value of a class attribute, we use this syntax:

�� Tip: You can use this syntax within the class as well.

How to Update a Class Attribute

To update a class attribute, we use this syntax:

How to Delete a Class Attribute

We use del to delete a class attribute. For example:

How to Define Methods

Methods represent the functionality of the instances of the class.

�� Tip: Instance methods can work with the attributes of the instance that is calling the method if we write self.<attribute> in the method definition.

This is the basic syntax of a method in a class. They are usually located below __init__ :

They may have zero, one, or more parameters if needed (just like functions!) but instance methods must always have self as the first parameter.

For example, here is a bark method with no parameters (in addition to self ):

To call this method, we use this syntax:

Here we have a Player class with an increment_speed method with one parameter:

To call the method:

�� Tip: to add more parameters, just separate them with a comma. It is recommended to add a space after the comma.

Properties, Getters and Setters in Python

Getters and setters are methods that we can define to get and set the value of an instance attribute, respectively. They work as intermediaries to «protect» the attributes from direct changes.

In Python, we typically use properties instead of getters and setters. Let’s see how we can use them.

To define a property, we write a method with this syntax:

This method will act as a getter, so it will be called when we try to access the value of the attribute.

Now, we may also want to define a setter:

And a deleter to delete the attribute:

�� Tip: you can write any code that you need in these methods to get, set, and delete an attribute. It is recommended to keep them as simple as possible.

This is an example:

If we add descriptive print statements, we can see that they are called when we perform their operation:

�� How to Work with Files in Python

Working with files is very important to create powerful programs. Let’s see how you can do this in Python.

How to Read Files in Python

In Python, it’s recommended to use a with statement to work with files because it opens them only while we need them and it closes them automatically when the process is completed.

To read a file, we use this syntax:

We can also specify that we want to open the file in read mode with an «r» :

But this is already the default mode to open a file, so we can omit it like in the first example.

This is an example:

�� Tip: that’s right! We can iterate over the lines of the file using a for loop. The file path can be relative to the Python script that we are running or it can be an absolute path.

How to Write to a File in Python

There are two ways to write to a file. You can either replace the entire content of the file before adding the new content, or append to the existing content.

To replace the content completely, we use the «w» mode, so we pass this string as the second argument to open() . We call the .write() method on the file object passing the content that we want to write as argument.

When you run the program, a new file will be created if it doesn’t exist already in the path that we specified.

This will be the content of the file:

How to Append to a File in Python

However, if you want to append the content, then you need to use the «a» mode:

This small change will keep the existing content of the file and it will add the new content to the end.

If we run the program again, these strings will be added to the end of the file:

How to Delete a File in Python

To delete a file with our script, we can use the os module. It is recommended to check with a conditional if the file exists before calling the remove() function from this module:

You might have noticed the first line that says import os . This is an import statement. Let’s see why they are helpful and how you can work with them.

�� Import Statements in Python

Organizing your code into multiple files as your program grows in size and complexity is good practice. But we need to find a way to combine these files to make the program work correctly, and that is exactly what import statements do.

By writing an import statement, we can import a module (a file that contains Python definitions and statements) into another file.

These are various alternatives for import statements:

First Alternative:

�� Tip: math is a built-in Python module.

If we use this import statement, we will need to add the name of the module before the name of the function or element that we are referring to in our code:

We explicitly mention in our code the module that the element belongs to.

Second Alternative:

In our code, we can use the new name that we assigned instead of the original name of the module:

Third Alternative:

With this import statement, we can call the function directly without specifiying the name of the module:

Fourth Alternative:

With this import statement, we can assign a new name to the element imported from the module:

Fifth Alternative:

This statement imports all the elements of the module and you can refer to them directly by their name without specifying the name of the module.

�� Tip: this type of import statement can make it more difficult for us to know which elements belong to which module, particularly when we are importing elements from multiple modules.

�� List and Dictionary Comprehension in Python

A really nice feature of Python that you should know about is list and dictionary comprehension. This is just a way to create lists and dictionaries more compactly.

List Comprehension in Python

The syntax used to define list comprehensions usually follows one of these four patterns:

�� Tip: you should only use them when they do not make your code more difficult to read and understand.

Here we have some examples:

List Comprehensions vs. Generator Expressions in Python

List comprehensions are defined with square brackets [] . This is different from generator expressions, which are defined with parentheses () . They look similar but they are quite different. Let’s see why.

  • List comprehensions generate the entire sequence at once and store it in memory.
  • Generator expressions yield the elements one at a time when they are requested.

We can check this with the sys module. In the example below, you can see that their size in memory is very different:

We can use generator expressions to iterate in a for loop and get the elements one at a time. But if we need to store the elements in a list, then we should use list comprehension.

Dictionary Comprehension in Python

Now let’s dive into dictionary comprehension. The basic syntax that we need to use to define a dictionary comprehension is:

Here we have some examples of dictionary comprehension:

This is an example with a conditional where we take an existing dictionary and create a new dictionary with only the students who earned a passing grade greater than or equal to 60:

I really hope you liked this article and found it helpful. Now you know how to write and work with the most important elements of Python.

⭐ Subscribe to my YouTube channel and follow me on Twitter to find more coding tutorials and tips. Check out my online course Python Exercises for Beginners: Solve 100+ Coding Challenges

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *