Перейти к содержимому

Как писать код на python

  • автор:

3. An Informal Introduction to Python¶

In the following examples, input and output are distinguished by the presence or absence of prompts ( >>> and … ): to repeat the example, you must type everything after the prompt, when the prompt appears; lines that do not begin with a prompt are output from the interpreter. Note that a secondary prompt on a line by itself in an example means you must type a blank line; this is used to end a multi-line command.

You can toggle the display of prompts and output by clicking on >>> in the upper-right corner of an example box. If you hide the prompts and output for an example, then you can easily copy and paste the input lines into your interpreter.

Many of the examples in this manual, even those entered at the interactive prompt, include comments. Comments in Python start with the hash character, # , and extend to the end of the physical line. A comment may appear at the start of a line or following whitespace or code, but not within a string literal. A hash character within a string literal is just a hash character. Since comments are to clarify code and are not interpreted by Python, they may be omitted when typing in examples.

3.1. Using Python as a Calculator¶

Let’s try some simple Python commands. Start the interpreter and wait for the primary prompt, >>> . (It shouldn’t take long.)

3.1.1. Numbers¶

The interpreter acts as a simple calculator: you can type an expression at it and it will write the value. Expression syntax is straightforward: the operators + , — , * and / work just like in most other languages (for example, Pascal or C); parentheses ( () ) can be used for grouping. For example:

The integer numbers (e.g. 2 , 4 , 20 ) have type int , the ones with a fractional part (e.g. 5.0 , 1.6 ) have type float . We will see more about numeric types later in the tutorial.

Division ( / ) always returns a float. To do floor division and get an integer result you can use the // operator; to calculate the remainder you can use % :

With Python, it is possible to use the ** operator to calculate powers 1:

The equal sign ( = ) is used to assign a value to a variable. Afterwards, no result is displayed before the next interactive prompt:

If a variable is not “defined” (assigned a value), trying to use it will give you an error:

There is full support for floating point; operators with mixed type operands convert the integer operand to floating point:

In interactive mode, the last printed expression is assigned to the variable _ . This means that when you are using Python as a desk calculator, it is somewhat easier to continue calculations, for example:

This variable should be treated as read-only by the user. Don’t explicitly assign a value to it — you would create an independent local variable with the same name masking the built-in variable with its magic behavior.

In addition to int and float , Python supports other types of numbers, such as Decimal and Fraction . Python also has built-in support for complex numbers , and uses the j or J suffix to indicate the imaginary part (e.g. 3+5j ).

3.1.2. Strings¶

Besides numbers, Python can also manipulate strings, which can be expressed in several ways. They can be enclosed in single quotes ( ‘. ‘ ) or double quotes ( ". " ) with the same result 2. \ can be used to escape quotes:

In the interactive interpreter, the output string is enclosed in quotes and special characters are escaped with backslashes. While this might sometimes look different from the input (the enclosing quotes could change), the two strings are equivalent. The string is enclosed in double quotes if the string contains a single quote and no double quotes, otherwise it is enclosed in single quotes. The print() function produces a more readable output, by omitting the enclosing quotes and by printing escaped and special characters:

If you don’t want characters prefaced by \ to be interpreted as special characters, you can use raw strings by adding an r before the first quote:

There is one subtle aspect to raw strings: a raw string may not end in an odd number of \ characters; see the FAQ entry for more information and workarounds.

String literals can span multiple lines. One way is using triple-quotes: """. """ or »’. »’ . End of lines are automatically included in the string, but it’s possible to prevent this by adding a \ at the end of the line. The following example:

produces the following output (note that the initial newline is not included):

Strings can be concatenated (glued together) with the + operator, and repeated with * :

Two or more string literals (i.e. the ones enclosed between quotes) next to each other are automatically concatenated.

This feature is particularly useful when you want to break long strings:

This only works with two literals though, not with variables or expressions:

If you want to concatenate variables or a variable and a literal, use + :

Strings can be indexed (subscripted), with the first character having index 0. There is no separate character type; a character is simply a string of size one:

Indices may also be negative numbers, to start counting from the right:

Note that since -0 is the same as 0, negative indices start from -1.

In addition to indexing, slicing is also supported. While indexing is used to obtain individual characters, slicing allows you to obtain substring:

Slice indices have useful defaults; an omitted first index defaults to zero, an omitted second index defaults to the size of the string being sliced.

Note how the start is always included, and the end always excluded. This makes sure that s[:i] + s[i:] is always equal to s :

One way to remember how slices work is to think of the indices as pointing between characters, with the left edge of the first character numbered 0. Then the right edge of the last character of a string of n characters has index n, for example:

The first row of numbers gives the position of the indices 0…6 in the string; the second row gives the corresponding negative indices. The slice from i to j consists of all characters between the edges labeled i and j, respectively.

For non-negative indices, the length of a slice is the difference of the indices, if both are within bounds. For example, the length of word[1:3] is 2.

Attempting to use an index that is too large will result in an error:

However, out of range slice indexes are handled gracefully when used for slicing:

Python strings cannot be changed — they are immutable . Therefore, assigning to an indexed position in the string results in an error:

If you need a different string, you should create a new one:

The built-in function len() returns the length of a string:

Strings are examples of sequence types, and support the common operations supported by such types.

Strings support a large number of methods for basic transformations and searching.

String literals that have embedded expressions.

Information about string formatting with str.format() .

The old formatting operations invoked when strings are the left operand of the % operator are described in more detail here.

3.1.3. Lists¶

Python knows a number of compound data types, used to group together other values. The most versatile is the list, which can be written as a list of comma-separated values (items) between square brackets. Lists might contain items of different types, but usually the items all have the same type.

Like strings (and all other built-in sequence types), lists can be indexed and sliced:

All slice operations return a new list containing the requested elements. This means that the following slice returns a shallow copy of the list:

Lists also support operations like concatenation:

Unlike strings, which are immutable , lists are a mutable type, i.e. it is possible to change their content:

You can also add new items at the end of the list, by using the append() method (we will see more about methods later):

Assignment to slices is also possible, and this can even change the size of the list or clear it entirely:

The built-in function len() also applies to lists:

It is possible to nest lists (create lists containing other lists), for example:

3.2. First Steps Towards Programming¶

Of course, we can use Python for more complicated tasks than adding two and two together. For instance, we can write an initial sub-sequence of the Fibonacci series as follows:

This example introduces several new features.

The first line contains a multiple assignment: the variables a and b simultaneously get the new values 0 and 1. On the last line this is used again, demonstrating that the expressions on the right-hand side are all evaluated first before any of the assignments take place. The right-hand side expressions are evaluated from the left to the right.

The while loop executes as long as the condition (here: a < 10 ) remains true. In Python, like in C, any non-zero integer value is true; zero is false. The condition may also be a string or list value, in fact any sequence; anything with a non-zero length is true, empty sequences are false. The test used in the example is a simple comparison. The standard comparison operators are written the same as in C: < (less than), > (greater than), == (equal to), <= (less than or equal to), >= (greater than or equal to) and != (not equal to).

The body of the loop is indented: indentation is Python’s way of grouping statements. At the interactive prompt, you have to type a tab or space(s) for each indented line. In practice you will prepare more complicated input for Python with a text editor; all decent text editors have an auto-indent facility. When a compound statement is entered interactively, it must be followed by a blank line to indicate completion (since the parser cannot guess when you have typed the last line). Note that each line within a basic block must be indented by the same amount.

The print() function writes the value of the argument(s) it is given. It differs from just writing the expression you want to write (as we did earlier in the calculator examples) in the way it handles multiple arguments, floating point quantities, and strings. Strings are printed without quotes, and a space is inserted between items, so you can format things nicely, like this:

The keyword argument end can be used to avoid the newline after the output, or end the output with a different string:

Since ** has higher precedence than — , -3**2 will be interpreted as -(3**2) and thus result in -9 . To avoid this and get 9 , you can use (-3)**2 .

Unlike other languages, special characters such as \n have the same meaning with both single ( ‘. ‘ ) and double ( ". " ) quotes. The only difference between the two is that within single quotes you don’t need to escape " (but you have to escape \’ ) and vice versa.

Основы языка программирования 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 имеют структуру try—except [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. Я надеюсь что эта статья поможет вам, если вы захотите и в дальнейшем изучать этот язык программирования.

PEP 8 — руководство по написанию кода на Python

Этот документ описывает соглашение о том, как писать код для языка python, включая стандартную библиотеку, входящую в состав python.

PEP 8 создан на основе рекомендаций Гуидо ван Россума с добавлениями от Барри. Если где-то возникал конфликт, мы выбирали стиль Гуидо. И, конечно, этот PEP может быть неполным (фактически, он, наверное, никогда не будет закончен).

Ключевая идея Гуидо такова: код читается намного больше раз, чем пишется. Собственно, рекомендации о стиле написания кода направлены на то, чтобы улучшить читаемость кода и сделать его согласованным между большим числом проектов. В идеале, весь код будет написан в едином стиле, и любой сможет легко его прочесть.

Это руководство о согласованности и единстве. Согласованность с этим руководством очень важна. Согласованность внутри одного проекта еще важнее. А согласованность внутри модуля или функции — самое важное. Но важно помнить, что иногда это руководство неприменимо, и понимать, когда можно отойти от рекомендаций. Когда вы сомневаетесь, просто посмотрите на другие примеры и решите, какой выглядит лучше.

Две причины для того, чтобы нарушить данные правила:

  1. Когда применение правила сделает код менее читаемым даже для того, кто привык читать код, который следует правилам.
  2. Чтобы писать в едином стиле с кодом, который уже есть в проекте и который нарушает правила (возможно, в силу исторических причин) — впрочем, это возможность переписать чужой код.

Содержание

Внешний вид кода

Отступы

Используйте 4 пробела на каждый уровень отступа.

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

Закрывающие круглые/квадратные/фигурные скобки в многострочных конструкциях могут находиться под первым непробельным символом последней строки списка, например:

либо быть под первым символом строки, начинающей многострочную конструкцию:

Табуляция или пробелы?

Пробелы — самый предпочтительный метод отступов.

Табуляция должна использоваться только для поддержки кода, написанного с отступами с помощью табуляции.

Python 3 запрещает смешивание табуляции и пробелов в отступах.

Python 2 пытается преобразовать табуляцию в пробелы.

Когда вы вызываете интерпретатор Python 2 в командной строке с параметром -t, он выдает предупреждения (warnings) при использовании смешанного стиля в отступах, а запустив интерпретатор с параметром -tt, вы получите в этих местах ошибки (errors). Эти параметры очень рекомендуются!

Максимальная длина строки

Ограничьте длину строки максимум 79 символами.

Для более длинных блоков текста с меньшими структурными ограничениями (строки документации или комментарии), длину строки следует ограничить 72 символами.

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

Некоторые команды предпочитают большую длину строки. Для кода, поддерживающегося исключительно или преимущественно этой группой, в которой могут прийти к согласию по этому вопросу, нормально увеличение длины строки с 80 до 100 символов (фактически увеличивая максимальную длину до 99 символов), при условии, что комментарии и строки документации все еще будут 72 символа.

Стандартная библиотека Python консервативна и требует ограничения длины строки в 79 символов (а строк документации/комментариев в 72).

Предпочтительный способ переноса длинных строк является использование подразумеваемых продолжений строк Python внутри круглых, квадратных и фигурных скобок. Длинные строки могут быть разбиты на несколько строк, обернутые в скобки. Это предпочтительнее использования обратной косой черты для продолжения строки.

Обратная косая черта все еще может быть использована время от времени. Например, длинная конструкция with не может использовать неявные продолжения, так что обратная косая черта является приемлемой:

Ещё один случай — assert.

Сделайте правильные отступы для перенесённой строки. Предпочтительнее вставить перенос строки после логического оператора, но не перед ним. Например:

Пустые строки

Отделяйте функции верхнего уровня и определения классов двумя пустыми строками.

Определения методов внутри класса разделяются одной пустой строкой.

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

Используйте пустые строки в функциях, чтобы указать логические разделы.

Python расценивает символ control+L как незначащий (whitespace), и вы можете использовать его, потому что многие редакторы обрабатывают его как разрыв страницы — таким образом логические части в файле будут на разных страницах. Однако, не все редакторы распознают control+L и могут на его месте отображать другой символ.

Кодировка исходного файла

Кодировка Python должна быть UTF-8 (ASCII в Python 2).

Файлы в ASCII (Python 2) или UTF-8 (Python 3) не должны иметь объявления кодировки.

В стандартной библиотеке, нестандартные кодировки должны использоваться только для целей тестирования, либо когда комментарий или строка документации требует упомянуть имя автора, содержащего не ASCII символы; в остальных случаях использование \x, \u, \U или \N — наиболее предпочтительный способ включить не ASCII символы в строковых литералах.

Начиная с версии python 3.0 в стандартной библиотеке действует следующее соглашение: все идентификаторы обязаны содержать только ASCII символы, и означать английские слова везде, где это возможно (во многих случаях используются сокращения или неанглийские технические термины). Кроме того, строки и комментарии тоже должны содержать лишь ASCII символы. Исключения составляют: (а) test case, тестирующий не-ASCII особенности программы, и (б) имена авторов. Авторы, чьи имена основаны не на латинском алфавите, должны транслитерировать свои имена в латиницу.

Проектам с открытым кодом для широкой аудитории также рекомендуется использовать это соглашение.

Импорты

Каждый импорт, как правило, должен быть на отдельной строке.

В то же время, можно писать так:

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

Импорты должны быть сгруппированы в следующем порядке:

  1. импорты из стандартной библиотеки
  2. импорты сторонних библиотек
  3. импорты модулей текущего проекта

Вставляйте пустую строку между каждой группой импортов.

Указывайте спецификации __all__ после импортов.

Рекомендуется абсолютное импортирование, так как оно обычно более читаемо и ведет себя лучше (или, по крайней мере, даёт понятные сообщения об ошибках) если импортируемая система настроена неправильно (например, когда каталог внутри пакета заканчивается на sys.path):

Тем не менее, явный относительный импорт является приемлемой альтернативой абсолютному импорту, особенно при работе со сложными пакетами, где использование абсолютного импорта было бы излишне подробным:

В стандартной библиотеке следует избегать сложной структуры пакетов и всегда использовать абсолютные импорты.

Неявные относительно импорты никогда не должны быть использованы, и были удалены в Python 3.

Когда вы импортируете класс из модуля, вполне можно писать вот так:

Если такое написание вызывает конфликт имен, тогда пишите:

И используйте «myclass.MyClass» и «foo.bar.yourclass.YourClass».

Шаблоны импортов (from import *) следует избегать, так как они делают неясным то, какие имена присутствуют в глобальном пространстве имён, что вводит в заблуждение как читателей, так и многие автоматизированные средства. Существует один оправданный пример использования шаблона импорта, который заключается в опубликовании внутреннего интерфейса как часть общественного API (например, переписав реализацию на чистом Python в модуле акселератора (и не будет заранее известно, какие именно функции будут перезаписаны).

Пробелы в выражениях и инструкциях

Избегайте использования пробелов в следующих ситуациях:

Непосредственно внутри круглых, квадратных или фигурных скобок.

Непосредственно перед запятой, точкой с запятой или двоеточием:

Сразу перед открывающей скобкой, после которой начинается список аргументов при вызове функции:

Сразу перед открывающей скобкой, после которой следует индекс или срез:

Использование более одного пробела вокруг оператора присваивания (или любого другого) для того, чтобы выровнять его с другим:

Другие рекомендации

Всегда окружайте эти бинарные операторы одним пробелом с каждой стороны: присваивания (=, +=, -= и другие), сравнения (==, <, >, !=, <>, <=, >=, in, not in, is, is not), логические (and, or, not).

Если используются операторы с разными приоритетами, попробуйте добавить пробелы вокруг операторов с самым низким приоритетом. Используйте свои собственные суждения, однако, никогда не используйте более одного пробела, и всегда используйте одинаковое количество пробелов по обе стороны бинарного оператора.

Не используйте пробелы вокруг знака =, если он используется для обозначения именованного аргумента или значения параметров по умолчанию.

Не используйте составные инструкции (несколько команд в одной строке).

Иногда можно писать тело циклов while, for или ветку if в той же строке, если команда короткая, но если команд несколько, никогда так не пишите. А также избегайте длинных строк!

Комментарии

Комментарии, противоречащие коду, хуже, чем отсутствие комментариев. Всегда исправляйте комментарии, если меняете код!

Комментарии должны являться законченными предложениями. Если комментарий — фраза или предложение, первое слово должно быть написано с большой буквы, если только это не имя переменной, которая начинается с маленькой буквы (никогда не изменяйте регистр переменной!).

Если комментарий короткий, можно опустить точку в конце предложения. Блок комментариев обычно состоит из одного или более абзацев, составленных из полноценных предложений, поэтому каждое предложение должно оканчиваться точкой.

Ставьте два пробела после точки в конце предложения.

Программисты, которые не говорят на английском языке, пожалуйста, пишите комментарии на английском, если только вы не уверены на 120%, что ваш код никогда не будут читать люди, не знающие вашего родного языка.

Блоки комментариев

Блок комментариев обычно объясняет код (весь, или только некоторую часть), идущий после блока, и должен иметь тот же отступ, что и сам код. Каждая строчка такого блока должна начинаться с символа # и одного пробела после него (если только сам текст комментария не имеет отступа).

Абзацы внутри блока комментариев разделяются строкой, состоящей из одного символа #.

«Встрочные» комментарии

Старайтесь реже использовать подобные комментарии.

Такой комментарий находится в той же строке, что и инструкция. «Встрочные» комментарии должны отделяться по крайней мере двумя пробелами от инструкции. Они должны начинаться с символа # и одного пробела.

Комментарии в строке с кодом не нужны и только отвлекают от чтения, если они объясняют очевидное. Не пишите вот так:

Впрочем, такие комментарии иногда полезны:

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

Пишите документацию для всех публичных модулей, функций, классов, методов. Строки документации необязательны для приватных методов, но лучше написать, что делает метод. Комментарий нужно писать после строки с def.

PEP 257 объясняет, как правильно и хорошо документировать. Заметьте, очень важно, чтобы закрывающие кавычки стояли на отдельной строке. А еще лучше, если перед ними будет ещё и пустая строка, например:

Для однострочной документации можно оставить закрывающие кавычки на той же строке.

Контроль версий

Если вам нужно использовать Subversion, CVS или RCS в ваших исходных кодах, делайте вот так:

Вставляйте эти строки после документации модуля перед любым другим кодом и отделяйте их пустыми строками по одной до и после.

Соглашения по именованию

Соглашения по именованию переменных в python немного туманны, поэтому их список никогда не будет полным — тем не менее, ниже мы приводим список рекомендаций, действующих на данный момент. Новые модули и пакеты должны быть написаны согласно этим стандартам, но если в какой-либо уже существующей библиотеке эти правила нарушаются, предпочтительнее писать в едином с ней стиле.

Главный принцип

Имена, которые видны пользователю как часть общественного API должны следовать конвенциям, которые отражают использование, а не реализацию.

Описание: Стили имен

Существует много разных стилей. Поможем вам распознать, какой стиль именования используется, независимо от того, для чего он используется.

Обычно различают следующие стили:

  • b (одиночная маленькая буква)
  • B (одиночная заглавная буква)
  • lowercase (слово в нижнем регистре)
  • lower_case_with_underscores (слова из маленьких букв с подчеркиваниями)
  • UPPERCASE (заглавные буквы)
  • UPPERCASE_WITH_UNDERSCORES (слова из заглавных букв с подчеркиваниями)
  • CapitalizedWords (слова с заглавными буквами, или CapWords, или CamelCase). Замечание: когда вы используете аббревиатуры в таком стиле, пишите все буквы аббревиатуры заглавными — HTTPServerError лучше, чем HttpServerError.
  • mixedCase (отличается от CapitalizedWords тем, что первое слово начинается с маленькой буквы)
  • Capitalized_Words_With_Underscores (слова с заглавными буквами и подчеркиваниями — уродливо!)

Ещё существует стиль, в котором имена, принадлежащие одной логической группе, имеют один короткий префикс. Этот стиль редко используется в python, но мы упоминаем его для полноты. Например, функция os.stat() возвращает кортеж, имена в котором традиционно имеют вид st_mode, st_size, st_mtime и так далее. (Так сделано, чтобы подчеркнуть соответствие этих полей структуре системных вызовов POSIX, что помогает знакомым с ней программистам).

В библиотеке X11 используется префикс Х для всех public-функций. В python этот стиль считается излишним, потому что перед полями и именами методов стоит имя объекта, а перед именами функций стоит имя модуля.

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

_single_leading_underscore: слабый индикатор того, что имя используется для внутренних нужд. Например, from M import * не будет импортировать объекты, чьи имена начинаются с символа подчеркивания.

single_trailing_underscore_: используется по соглашению для избежания конфликтов с ключевыми словами языка python, например:

__double_leading_underscore: изменяет имя атрибута класса, то есть в классе FooBar поле __boo становится _FooBar__boo.

__double_leading_and_trailing_underscore__ (двойное подчеркивание в начале и в конце имени): магические методы или атрибуты, которые находятся в пространствах имен, управляемых пользователем. Например, __init__, __import__ или __file__. Не изобретайте такие имена, используйте их только так, как написано в документации.

Предписания: соглашения по именованию

Имена, которых следует избегать

Никогда не используйте символы l (маленькая латинская буква «эль»), O (заглавная латинская буква «о») или I (заглавная латинская буква «ай») как однобуквенные идентификаторы.

В некоторых шрифтах эти символы неотличимы от цифры один и нуля. Если очень нужно l, пишите вместо неё заглавную L.

Имена модулей и пакетов

Модули должны иметь короткие имена, состоящие из маленьких букв. Можно использовать символы подчеркивания, если это улучшает читабельность. То же самое относится и к именам пакетов, однако в именах пакетов не рекомендуется использовать символ подчёркивания.

Так как имена модулей отображаются в имена файлов, а некоторые файловые системы являются нечувствительными к регистру символов и обрезают длинные имена, очень важно использовать достаточно короткие имена модулей — это не проблема в Unix, но, возможно, код окажется непереносимым в старые версии Windows, Mac, или DOS.

Когда модуль расширения, написанный на С или C++, имеет сопутствующий python-модуль (содержащий интерфейс высокого уровня), С/С++ модуль начинается с символа подчеркивания, например, _socket.

Имена классов

Имена классов должны обычно следовать соглашению CapWords.

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

Обратите внимание, что существуют отдельные соглашения о встроенных именах: большинство встроенных имен — одно слово (либо два слитно написанных слова), а соглашение CapWords используется только для именования исключений и встроенных констант.

Имена исключений

Так как исключения являются классами, к исключениям применяется стиль именования классов. Однако вы можете добавить Error в конце имени (если, конечно, исключение действительно является ошибкой).

Имена глобальных переменных

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

Добавляйте в модули, которые написаны так, чтобы их использовали с помощью from M import *, механизм __all__, чтобы предотвратить экспортирование глобальных переменных. Или же, используйте старое соглашение, добавляя перед именами таких глобальных переменных один символ подчеркивания (которым вы можете обозначить те глобальные переменные, которые используются только внутри модуля).

Имена функций

Имена функций должны состоять из маленьких букв, а слова разделяться символами подчеркивания — это необходимо, чтобы увеличить читабельность.

Стиль mixedCase допускается в тех местах, где уже преобладает такой стиль, для сохранения обратной совместимости.

Аргументы функций и методов

Всегда используйте self в качестве первого аргумента метода экземпляра объекта.

Всегда используйте cls в качестве первого аргумента метода класса.

Если имя аргумента конфликтует с зарезервированным ключевым словом python, обычно лучше добавить в конец имени символ подчеркивания, чем исказить написание слова или использовать аббревиатуру. Таким образом, class_ лучше, чем clss. (Возможно, хорошим вариантом будет подобрать синоним).

Имена методов и переменных экземпляров классов

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

Используйте один символ подчёркивания перед именем для непубличных методов и атрибутов.

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

Python искажает эти имена: если класс Foo имеет атрибут с именем __a, он не может быть доступен как Foo.__a. (Настойчивый пользователь все еще может получить доступ, вызвав Foo._Foo__a.) Вообще, два ведущих подчеркивания должны использоваться только для того, чтобы избежать конфликтов имен с атрибутами классов, предназначенных для наследования.

Примечание: есть некоторые разногласия по поводу использования __ имена (см. ниже).

Константы

Константы обычно объявляются на уровне модуля и записываются только заглавными буквами, а слова разделяются символами подчеркивания. Например: MAX_OVERFLOW, TOTAL.

Проектирование наследования

Обязательно решите, каким должен быть метод класса или экземпляра класса (далее — атрибут) — публичный или непубличный. Если вы сомневаетесь, выберите непубличный атрибут. Потом будет проще сделать его публичным, чем наоборот.

Публичные атрибуты — это те, которые будут использовать другие программисты, и вы должны быть уверены в отсутствии обратной несовместимости. Непубличные атрибуты, в свою очередь, не предназначены для использования третьими лицами, поэтому вы можете не гарантировать, что не измените или не удалите их.

Мы не используем термин «приватный атрибут», потому что на самом деле в python таких не бывает.

Другой тип атрибутов классов принадлежит так называемому API подклассов (в других языках они часто называются protected). Некоторые классы проектируются так, чтобы от них наследовали другие классы, которые расширяют или модифицируют поведение базового класса. Когда вы проектируете такой класс, решите и явно укажите, какие атрибуты являются публичными, какие принадлежат API подклассов, а какие используются только базовым классом.

Теперь сформулируем рекомендации:

Открытые атрибуты не должны иметь в начале имени символа подчеркивания.

Если имя открытого атрибута конфликтует с ключевым словом языка, добавьте в конец имени один символ подчеркивания. Это более предпочтительно, чем аббревиатура или искажение написания (однако, у этого правила есть исключение — аргумента, который означает класс, и особенно первый аргумент метода класса (class method) должен иметь имя cls).

Назовите простые публичные атрибуты понятными именами и не пишите сложные методы доступа и изменения (accessor/mutator, get/set, — прим. перев.) Помните, что в python очень легко добавить их потом, если потребуется. В этом случае используйте свойства (properties), чтобы скрыть функциональную реализацию за синтаксисом доступа к атрибутам.

Примечание 1: Свойства (properties) работают только в классах нового стиля (в Python 3 все классы являются таковыми).

Примечание 2: Постарайтесь избавиться от побочных эффектов, связанным с функциональным поведением; впрочем, такие вещи, как кэширование, вполне допустимы.

Примечание 3: Избегайте использования вычислительно затратных операций, потому что из-за записи с помощью атрибутов создается впечатление, что доступ происходит (относительно) быстро.

Если вы планируете класс таким образом, чтобы от него наследовались другие классы, но не хотите, чтобы подклассы унаследовали некоторые атрибуты, добавьте в имена два символа подчеркивания в начало, и ни одного — в конец. Механизм изменения имен в python сработает так, что имя класса добавится к имени такого атрибута, что позволит избежать конфликта имен с атрибутами подклассов.

Примечание 1: Будьте внимательны: если подкласс будет иметь то же имя класса и имя атрибута, то вновь возникнет конфликт имен.

Примечание 2: Механизм изменения имен может затруднить отладку или работу с __getattr__(), однако он хорошо документирован и легко реализуется вручную.

Примечание 3: Не всем нравится этот механизм, поэтому старайтесь достичь компромисса между необходимостью избежать конфликта имен и возможностью доступа к этим атрибутам.

Общие рекомендации

Код должен быть написан так, чтобы не зависеть от разных реализаций языка (PyPy, Jython, IronPython, Pyrex, Psyco и пр.).

Например, не полагайтесь на эффективную реализацию в CPython конкатенации строк в выражениях типа a+=b или a=a+b. Такие инструкции выполняются значительно медленнее в Jython. В критичных к времени выполнения частях программы используйте ».join() — таким образом склеивание строк будет выполнено за линейное время независимо от реализации python.

Сравнения с None должны обязательно выполняться с использованием операторов is или is not, а не с помощью операторов сравнения. Кроме того, не пишите if x, если имеете в виду if x is not None — если, к примеру, при тестировании такая переменная может принять значение другого типа, отличного от None, но при приведении типов может получиться False!

При реализации методов сравнения, лучше всего реализовать все 6 операций сравнения (__eq__, __ne__, __lt__, __le__, __gt__, __ge__), чем полагаться на то, что другие программисты будут использовать только конкретный вид сравнения.

Для минимизации усилий можно воспользоваться декоратором functools.total_ordering() для реализации недостающих методов.

PEP 207 указывает, что интерпретатор может поменять y > х на х < y, y >= х на х <= y, и может поменять местами аргументы х == y и х != y. Гарантируется, что операции sort() и min() используют оператор <, а max() использует оператор >. Однако, лучше всего осуществить все шесть операций, чтобы не возникало путаницы в других местах.

Всегда используйте выражение def, а не присваивание лямбда-выражения к имени.

Наследуйте свой класс исключения от Exception, а не от BaseException. Прямое наследование от BaseException зарезервировано для исключений, которые не следует перехватывать.

Используйте цепочки исключений соответствующим образом. В Python 3, «raise X from Y» следует использовать для указания явной замены без потери отладочной информации.

Когда намеренно заменяется исключение (использование «raise X» в Python 2 или «raise X from None» в Python 3.3+), проследите, чтобы соответствующая информация передалась в новое исключение (такие, как сохранение имени атрибута при преобразовании KeyError в AttributeError или вложение текста исходного исключения в новом).

Когда вы генерируете исключение, пишите raise ValueError(‘message’) вместо старого синтаксиса raise ValueError, message.

Старая форма записи запрещена в python 3.

Такое использование предпочтительнее, потому что из-за скобок не нужно использовать символы для продолжения перенесенных строк, если эти строки длинные или если используется форматирование.

Когда код перехватывает исключения, перехватывайте конкретные ошибки вместо простого выражения except:.

К примеру, пишите вот так:

Простое написание «except:» также перехватит и SystemExit, и KeyboardInterrupt, что породит проблемы, например, сложнее будет завершить программу нажатием control+C. Если вы действительно собираетесь перехватить все исключения, пишите «except Exception:».

Хорошим правилом является ограничение использования «except:», кроме двух случаев:

  1. Если обработчик выводит пользователю всё о случившейся ошибке; по крайней мере, пользователь будет знать, что произошла ошибка.
  2. Если нужно выполнить некоторый код после перехвата исключения, а потом вновь «бросить» его для обработки где-то в другом месте. Обычно же лучше пользоваться конструкцией «try. finally».

При связывании перехваченных исключений с именем, предпочитайте явный синтаксис привязки, добавленный в Python 2.6:

Это единственный синтаксис, поддерживающийся в Python 3, который позволяет избежать проблем неоднозначности, связанных с более старым синтаксисом на основе запятой.

При перехвате ошибок операционной системы, предпочитайте использовать явную иерархию исключений, введенную в Python 3.3, вместо анализа значений errno.

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

Когда ресурс является локальным на участке кода, используйте выражение with для того, чтобы после выполнения он был очищен оперативно и надёжно.

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

Последний пример не дает никакой информации, указывающей на то, что __enter__ и __exit__ делают что-то кроме закрытия соединения после транзакции. Быть явным важно в данном случае.

Используйте строковые методы вместо модуля string — они всегда быстрее и имеют тот же API для unicode-строк. Можно отказаться от этого правила, если необходима совместимость с версиями python младше 2.0.

В Python 3 остались только строковые методы.

Пользуйтесь ».startswith() и ».endswith() вместо обработки срезов строк для проверки суффиксов или префиксов.

startswith() и endswith() выглядят чище и порождают меньше ошибок. Например:

Сравнение типов объектов нужно делать с помощью isinstance(), а не прямым сравнением типов:

Когда вы проверяете, является ли объект строкой, обратите внимание на то, что строка может быть unicode-строкой. В python 2 у str и unicode есть общий базовый класс, поэтому вы можете написать:

Отметим, что в Python 3, unicode и basestring больше не существуют (есть только str) и bytes больше не является своего рода строкой (это последовательность целых чисел).

Для последовательностей (строк, списков, кортежей) используйте тот факт, что пустая последовательность есть false:

Изучение Python: от нуля до мастера

Первым делом спросим себя, что такое Python? Создатель языка, Гвидо ван Россум, описывает его следующим образом:

“Язык программирования высокого уровня, главная идея которого — это простая читабельность и синтаксис, который позволяет программистам выражать концепцию программы парой строк кода”

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

Следующей причиной было то, что Python мультизадачный. Мы можем его использовать для анализирования данных, разработки сайтов, машинного обучения. Quora, Pinterest и Spotify используют именно Python для своего back-end’а. Хорошая мотивация, чтобы узнать чуть больше об этом.

Основы

1. Переменные

Вы можете думать о переменных, как о словах, что держат в себе какое-то значение. Очень просто.

В Python нет ничего проще, чем определить переменную и присвоить ей какое-то значение. Представьте, что мы ходим сохранить число 1 в переменной, которую назовём “one”. Это будет выглядеть следующим образом

Что может быть проще? И при этом вы только что присвоили значение 1 для переменной “one”.

И таким образом вы можете присвоить любое значение любой переменной. И как видно в примере кода повыше, переменная “two” хранит числовое значение 2, а переменная “some_number” хранит значение 10,000.

Помимо числовых значений, мы также можем использовать логические (true/false, в переводе истинно/ложно), строки, десятичные числа и много других типов.

2. Контролирование потока: условные состояния

Ключевое слово “if” используется для ситуаций, когда нам нужно выполнить разные действия при положительных или отрицательных условиях. При значении “истинно” будет выполняться описанный после слова “if” блок, например:

2 больше, чем 1, поэтому выполняется “print”-команда.

Блок “else” выполнится при условии, если условие “if” ложно.

Так как 1 не больше 2, то выполняется в блоке “else”.

Также можно использовать “elif” условие:

3. Циклы / итерации

В Python, можно создавать циклы различными способами. Мы расскажем о двух: while и for.

Цикл While: до тех пор, пока условие истинно, код внутри цикла будет выполняться. Таким образом, следующий код напишет числа от 1 до 10.

Циклу while нужно “условие повтора”. Если оно остаётся истинным, итерации продолжаются. В приведённом примере, когда значение num становится 11, условие цикла становится ложным.

Ещё один небольшой пример, чтобы лучше понять цикл while:

Условие цикла(loop condition) установлено в True, поэтому цикл будет выполняться до тех пор, пока мы не переключим его в значение False.

Цикл for: в цилке for мы назначаем переменную “num” для самого цикла, который в свою очередь будет увеличивать значение этой переменной. Следующий код напишет числа от 1 до 10 точно так же, как и цикл while:

Видите? Очень просто. Цикл начинается с 1 и продолжается до 11 элемента.

Списки: коллекция, массив, структура данных

Представьте что вы хотите сохранить значение 1 в переменной. или может теперь вы хотите сохранить 2. А ещё 3, 4, 5…

Есть ли иной способ хранить все числа, что нам нужны, не имея при этом, не создавая при этом миллионы переменных? Как оказывается, есть иной способ хранить их всех.

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

Это действительно просто. Мы создали список и сохранили его в my_integers.

Но затем мы спросим себя: “А как нам получить нужное значение из списка?”.

Хороший вопрос. В списках есть концепция, которая зовётся номером(индексом). Номером первого элемента в списке является 0, следующий получает 1 и так далее.

Чтобы донести это проще, мы можем представить список, у которого каждый элемент подписан своим номером. Как на следующей картинке:

Используя синтаксис Python не сложно понять и следующее:

Представьте, что мы больше не хотим хранить числа. Вместо этого мы хотим составить список имён наших знакомых. Мой выглядел бы следующим образом:

Это работает точно так же, как и с числами. Неплохо.

Только что мы выучили, как работают индексы в списках. Но мне всё ещё нужно показать вам, как добавить новый элемент в список.

Самая простая функция, которую можно использовать для этого — зовётся append. Работает она следующим образом:

Функция append донельзя проста. Вам всего лишь нужно использовать новый элемент(в примере выше это “The Effective Engineer”) как значение это функции.

Ну что же, достаточно о списках. Перейдём к следующей структуре данных.

Словарь: структура данных в виде ключ-значение

Теперь мы знаем, что списки пронумерованы числовыми значениями. Но что, если мы не хотим использовать числа для идентификации элемента? Некоторые виды структур данных могут использовать числа, строки, или другие виды идентификации.

Одним из таких типов является словарь. Словарь это коллекция пар ключ-значение. Вот так это выглядит:

Ключ указывает на значение. Чтобы получить доступ к какому-либо значению — нам нужно обратиться к его ключу. Делается это следующим образом:

Я создал словарь о себе. Моё имя, никнейм и национальность. Эти атрибуты ключи в словаре.

Похожим образом на то, как мы получаем элемент из списка по его номеру, точно так же мы получаем значения словарей по их ключам.

В примере я написал предложение о себе используя значения, которые хранятся в словаре. Довольно просто, не правда ли?

Ещё одной хорошей особенностью словарей является то, что мы можем использовать что угодно в качестве значения. В том словаре, что я создал, я хочу добавить новый ключ “age”(возраст) и числом мой реальный возраст в качестве значения:

Здесь у нас пара из ключа(age) и значения(24). При этом ключ это строка, а значение это число.

Точно также как со списками, давайте научимся добавлять новый элемент в словарь. Ключ указывающий на значение — главная особенность словаря. И это же одна из особенностей при добавлении нового элемента в словарь:

Нам просто нужно дописать значение для существующего ключа в словаре. Ничего сложного, не так ли?

Итерации: циклы для структур данных

Как описывалось выше — итерации в списках довольно просты. Обычно Python-разработчики используют цикл for. Давайте посмотрим как это выглядит:

Таким образом, за каждую книгу на книжной полке(bookshelf) мы вызываем функцию print. Достаточно просто и интуитивно. Это Python.

Для хэш-структуры данных мы используем тот же цикл for, но в качестве счётчика выступает key:

Это пример того как мы используем этот цикл. За каждый ключ в словаре, мы используем print для вывода ключа и его значения.

Также есть другой способ сделать это используя функцию iteritems.

Мы назвали наши параметры как key и value, но в этом нет необходимости. Мы можем назвать их как угодно. Давайте проверим это:

В данном примере мы использовали attribute, как параметр для ключей словаря. Как видим, всё работает корректно. Отлично!

Классы и объекты

Немного теории:

Объекты это представление предметов из реальной жизни, например машин, собак, велосипедов. У объектов есть две основных характеристики: данные и поведение.

У машин есть данные, например количество колёс или сидячих мест. Также у них есть поведение: они могут разгоняться, останавливаться, показывать оставшееся количество топлива и другое.

В объектно-ориентированном программировании мы идентифицируем данные как атрибуты, а поведение как методы. Ещё раз:

Данные → Атрибуты; Поведение → Методы

Класс это как чертёж, из которого создаются уникальные объекты. В реальном мире есть множество объектов с похожими характеристиками. Например, машины. Все они имеют какую-то марку или модель(точно так же как и двигатель, колёса, двери и так далее). Каждая машина была построена из похожего набора чертежей и деталей.

Активировать объектно-ориентированный режим Python

Python, как объектно-ориентированный язык программирования, имеет следующие концепции: классы и объекты.

Класс — это чертёж, модель для его объектов.

Ещё раз, класс — это просто модель, или способ для определения атрибутов и поведения(о которых мы говорили в теории выше). Например, класс машины будет иметь свои собственные атрибуты, которые определяют какие объекты являются машинами. Количество колёс, тип топлива, количество сидячих мест и максимальная скорость — всё это является атрибутами машин.

Держа это в уме, давайте посмотрим на синтаксис Python для классов:

Мы определяем классы class-блоком и на этом всё. Легко, не так ли?

Объекты это экземпляры классов. Мы создаём экземпляр тогда, когда даём классу имя.

Здесь car это объект(экземпляр) класса Vehicle.

Помните, что наш класс машин имеет следующие атрибуты: количество колёс, тип топлива, количество сидячих мест и максимальная скорость. Мы задаём все атрибуты когда создаём объект машины. В коде ниже, мы описываем наш класс таким образом, чтобы он принимал данные в тот момент, когда его инициализируют:

Мы используем метод init. Мы называем этот конструктор-методом. Таким образом, когда мы создаём объект машины, мы можем ещё и определить его атрибуты. Представьте, что нам нравится модель Tesla S и мы хотим создать её как наш объект. У неё есть четыре колеса, она работает на электрической энергии, есть пять сидячих мест и максимальная скорость составляет 250 км/ч. Давайте создадим такой объект:

Четыре колеса + электрический “вид топлива” + пять сидений + 250 км/ч как максимальная скорость.

Все атрибуты заданы. Но как нам теперь получить доступ к значениям этих атрибутов? Мы посылаем объекту сообщению с запросом атрибутов. Мы называем это метод. Это поведение объекта. Давайте воплотим эту идею:

Это реализация двух методов: number_of_wheels и set_number_of_wheels. Мы называем их получатель и установщик. Потому что получатель принимает значение атрибута, а установщик задаёт ему новое значение.

В Python мы можем реализовать это используя @property для описания получателя и установщика. Посмотрим на это в коде:

Далее мы можем использовать методы как атрибуты:

Это немного отличается от описания методов. Эти методы работают как атрибуты. Например, когда мы задаём количество колёс, то не применяем два как параметр, а устанавливаем значение двойки для number_of_wheels. Это один из способ написать получать и установщик в Python.

Ещё мы можем использовать методы для других вещей, например создать метод “make_noise”(пошуметь).

Когда мы вызовем этот метод, он просто вернётся строку “VRRRRUUUUM”.

Инкапсуляция: сокрытие информации

Инкапсуляция — это механизм, который ограничивает свободный доступ к данным и методам объекта. Но в то же время, это упрощает доступ к данным(методам объекта).

“Инкапсуляция может использоваться для сокрытия данных и функций. Под определением инкапсуляции имеется ввиду то, что внутреннее представление объекта сокрыто от просмотра вне определения объекта.” — Википедия

Вся внутренняя реализация объекта недоступна извне. Только сам объект может взаимодействовать со своими внутренними данными.

Для начала нам нужно понять как работают публичные и не-публичные переменные и методы.

Публичные экземпляры данных

Для Python-класса мы можем инициализировать публичный экземпляр переменной внутри нашего конструктор-метода. Давайте посмотрим:

Здесь мы применяем значение first_name как аргумент для публичного экземпляра переменной.

Здесь нам не нужно применять first_name как аргумент, а все экземпляры объектов будут иметь заранее прописанный атрибут класса. В нашем случае first_name будет заполнено строкой “ТК.

Круто. Теперь мы узнали как можно использовать публичные экземпляры переменных и атрибуты класса. Ещё одна интересная особенность публичных данных в том, что мы можем управлять значениями переменных. Что я имею в виду под этим? Наш объект может управлять значением переменной: получать и устанавливать значения переменной.

Помня о классе person зададим значение для переменной first_name

Вот и всё. Мы просто задали другое значение(kaio) экземпляру переменной first_name и оно обновилось. И всё на этом. Поскольку это публичная переменная, то мы можем делать это так.

Не-публичные экземпляры данных

Мы не используем термин “приватный”, поскольку в Python нет действительно приватных атрибутов(если только не задаваться тяжёлой целью создать их). — PEP 8

Точно так же, как с публичными экземплярами переменных, мы можем объявить и не-публичные экземпляры. Оба внутри конструктор-метода или внутри класса. Синтаксис несколько отличается: не-публичные экземпляры переменных должны начинаться с нижнего подчёркивания(“_”) перед именем переменной.

“‘Приватный’ экземпляр данных, доступ к которому открыт только изнутри, не существует в Python. Тем не менее, есть условность, которая выполняется в большей части Python-кода: имена с префиксом “_”(например, “_spam”) должны обрабатываться как не-публичные части API(будь то функция, метод или какие-то данные)” — Python Software Foundation

Увидели переменную email? Вот так мы описываем не-публичную переменную:

Мы имеем доступ и может обновить это. Не-публичные переменные это условность, при которой эти переменные обрабатываются как не-публичная часть API.

Таким образом мы создаём метод, который позволяет нам вносить изменения внутри определения класса. Давайте реализуем два метода(email и update_email), чтобы понять это:

Теперь мы имеем доступ и можем обновить значения не-публичных переменных используя эти методы. Посмотрим:

  1. Мы объявили новый объект, в котором first_name заполнено строкой “ТК” и email заполнено строкой “tk@mail.com”
  2. Выводим email получая доступ к не-публичной переменной через метод
  3. Пробуем задать новый email извне нашего класса
  4. Нам нужно обращаться в не-публичной переменной как к не-публичной части API
  5. Обновляем нашу не-публичную переменную с нашим методом экземпляра
  6. Успех! Мы можем обновить это внутри нашего метода с помощью метода-помощника

Публичные методы

Публичные методы мы тоже можем использовать вне класса:

Давайте протестируем это:

Прекрасно. Мы можем использовать это без каких-либо проблем.

Не-публичные методы

Но не-публичные методы мы не можем использовать так просто. Давайте реализуем тот же класс Person, но теперь метод show_age станет не-публичным с нижним подчёркиванием.

А теперь попробуем вызвать этот не-публичный метод с помощью нашего объекта:

У нас есть доступ и мы можем обновить это. Не-публичные методы это просто условность, при которых они обрабатываются как не-публичная часть API.

Здесь пример того, как мы можем использовать это:

Здесь у нас есть не-публичный метод _get_age и публичный метод show_age. show_age может использоваться нашим объектом(вне класса), в то время как _get_age используется только внутри определения нашего класса(внутри метода show_age). Но опять же, в виду условностей.

Вывод об инкапсуляции

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

Наследование: поведение и характеристики

Разные объекты могут иметь некоторую схожесть, обладать поведением и характеристиками.

Например, я унаследовал какие-то характеристики и поведение от своего отца. Я получил его глаза и волосы в качестве своих характеристик, а его нетерпеливость и интровертность в качестве своего поведения.

В объектно-ориентированном программировании классы могут наследовать простые характеристики(данные) и поведение(методы) от других классов.

Давайте посмотрим другой пример и реализуем его в Python.

Представьте машину. Количество колёс, сидячих мест и максимальная скорость — всё это атрибуты машины. Мы можем сказать, что класс электромашины наследует эти схожие характеристики от обычного класса машины.

Наш класс машины реализует:

Один раз реализовав, мы можем использовать все созданные экземпляры переменных. Неплохо.

В Python, мы применяем класс-родитель к нашему классу-наследнику как параметр. Класс электромашины может наследоваться от класса машины.

Вот так просто. Нам не нужно реализовывать какой-либо другой метод, потому что этот класс уже имеет его(унаследовав от класса машины). Давайте докажем это:

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

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

Luxury Car Rental in Miami | Reserve a Premium Vehicle with RealCar