Язык программирования Python — подробно для начинающих

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

Для изучения языка Python я также рекомендую книгу «Язык программирования Python», авторы: Г. Россум, Ф.Л.Дж. Дрейк, Д.С. Откидач. Написано очень последовательно и доступным языком.

Содержание

Нюансы Python

Объекто-ориентированность

Это для начинающих можно пока пропустить, и вернуться после прочтения остального материала!

>>> q = [2, 3]
>>> p = [1, q, 4]
>>> len(p)
3
>>> p[1]
[2, 3]
>>> p[1][0]
2
>>> p[1].append(’xtra’)
>>> p
[1, [2, 3, ’xtra’], 4]
>>> q
[2, 3, ’xtra’]

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

То есть вы можете присвоить переменной определение класса:

>>> class MyClass:
...   i = 12345
...   def f(x):
...     print dir(x)
...     return x
...
>>> c = MyClass()
>>> i
123
>>> c.i
12345
>>> c.f
<bound method MyClass.f of <__main__.MyClass instance at 0x000000000239E7C8>>
>>> d=MyClass
>>> e=MyClass()
>>> e
<__main__.MyClass instance at 0x000000000239E808>
>>> c
<__main__.MyClass instance at 0x000000000239E7C8>
>>> d
<class __main__.MyClass at 0x000000000243A948>
>>> d.i
12345
>>> c.i
12345
>>> c.f
<bound method MyClass.f of <__main__.MyClass instance at 0x000000000239E7C8>>
>>> e.f
<bound method MyClass.f of <__main__.MyClass instance at 0x000000000239E808>>
>>> d.f
<unbound method MyClass.f>
>>> g = d()
>>> g.f
<bound method MyClass.f of <__main__.MyClass instance at 0x000000000244CA08>>

Отступы

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

def some_func(z):
    y = z*2  # Тело функции
    return y # Это - тоже функция

# А это - уже нет
y = 1
print(some_func(y))

Переменные в Python

Целые числа и числа с плавающей запятой

Присваивая цисло в переменную без точки или с помощью int(), вы получите переменную целого типа. Результат деления двух чисел целого типа также будет целым числом — остаток от деления будет отброшен.

Добавьте к числу точку в конце, чтобы создать переменную типа float:

x = 2.0

Строки в Python

Подстановка значений в строку

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

Есть два варианта подставить значения в строку: позиционная подстановка и использование именованных параметров.

Позиционная подстановка значений

output = 'Product %s in category %s' % (product, category)
output = 'You have %s $' % usd_count

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

Использование именованных параметров

output = 'Today is %(month)s %(day)s.') % {'month': m, 'day': d}

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

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

Форматирование и вывод строк

Завершающая запятая позволяет после вывода значения вставлять пробел вместо перехода на новую строку:

>>> while b < 10:
... print b,
... b += 1
...
1 2 3 4 5 6 7 8 9
>>> for x in range(1, 11):
...     print str(x).rjust(2), str(x*x).rjust(3),
...     # Обратите внимание на запятую в конце предыдущей строки!
...     print str(x*x*x).rjust(4)
...

Отформатированный вывод:

 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000

Этот пример демонстрирует использование метода строк rjust(), который выравнивает строку вправо в поле заданной ширины, дополняя ее слева пробелами. Ана-логично действуют методы ljust() и center(). Они не выводят ничего — просто возвращают новую строку. Если исходная строка слишком длинная, она не обрезается, а возвращается в неизменном виде: обычно лучше внести беспорядок в расположение колонок, чем вывести неверное значение. (Если Вы действительно хотите ее обрезать, воспользуйтесь операцией среза: ‘s.ljust(n)[0:n]’.)

Также может быть полезна функция zfill(), определенная в модуле string,
которая дополняет слева нулями строку с числом, корректно обрабатывая знаки плюс и минус:

>>> import string
>>> string.zfill(’12’, 5)
’00012’
>>> string.zfill(’-3.14’, 7)
’-003.14’
>>> string.zfill(’3.14159265359’, 5)
’3.14159265359’

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

>>> import math
>>> print ’Значение PI примерно равно %5.3f.’ % \
... math.pi
Значение PI примерно равно 3.142.

% для вывода информации в 3 столбца:

>>> for x in range(1,11):
...     print ’%2d %3d %4d’ % (x, x*x, x*x*x)
...
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000

Операции и операнды

Присваивание

Можно присвоить значение сразу нескольким переменным

a = b = c = 1
a, b = 0, 1

Возведение в степень

5 в степени 2 (5 в квадрате):

print 5**2

Логические условия

Операторы in и not in проверяют, есть указанное значение в последовательности. Операторы is и is not определяют, ссылаются ли две переменные на один и тот же объект. Все эти операторы имеют одинаковый приоритет, который ниже, чем у арифметических операторов.

Логические выражения могут быть сцеплены: например, ‘a < b == c’ проверяет,
меньше ли a чем b и равны ли b и c.

Логические выражения можно группировать с помощью логических операторов
and и or, а также результат можно инвертировать оператором not. Все логические
операторы имеют меньший приоритет, чем операторы сравнения. Среди логических операторов, not имеет наибольший приоритет и or — наименьший.

Встроенные в Python функции

Все встроенные в язык фунции можно посмотреть здесь:

https://docs.python.org/2/library/functions.html

Циклы

Цикл While

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

while expr: suite1
[else: suite2]

Инструкция while выполняется в следующем порядке:

1. Вычисляется выражение expr и, если оно дает ложь, переходит к пункту 3.
2. Выполняется блок кода suite1. При этом выполнение в блоке инструкции break
немедленно прерывает выполнение цикла (пункт 3 не выполняется), а выполнение
инструкции continue прерывает выполнение блока кода, после чего выполнение
цикла продолжается с пункта 1. После окончания выполнения блока suite1, вы-
полнение цикла продолжается с пункта 1.
3. Выполняется блок кода suite2 (ветвь else). Инструкции break и continue в
этом блоке считаются относящимися к внешнему циклу.

Цикл For

Цикл for в языке Python перебирает элементы произвольной последовательности (например, списка или строки) в порядке их следования:

... a = [’кот’, ’окно’, ’выбросить’]
>>> for x in a:
... print x, len(x)
...
кот 3
окно 4
выбросить 9

Особенности работы цикла for в Python

Инструкция for используется для перебора элементов последовательности:

for lvalue in sequence: 
    suite1
[else: 
    suite2]

Выражение sequence вычисляется один раз и должно давать последовательность (объект, для которого определена операция получения элемента по индексу; если индекс выходит за пределы диапазона, должно генерироваться исключение IndexError).

Для каждого элемента последовательности sequence в порядке возрастания индексов, начиная с 0, выполняется присваивание lvalue элемента последовательности и выполняется блок кода suite1.

После того как последовательность исчерпана (определяется по сгенерированному исключению IndexError), если присутствует ветвь else, выполняется блок suite2.

Выполнение инструкции break в блоке suite1 немедленно прерывает выполнение цикла (ветвь else игнорируется). При выполнении инструкции continue в блоке suite1 пропускается остаток блока и выполнение цикла продолжается после присваивания lvalue следующего элемента последовательности sequence или выполняется ветвь else, если в последовательности нет следующего элемента.

Вы можете присваивать переменной или переменным, входящим в lvalue, — это никак не отразится на следующем элементе, который будет присвоен lvalue. Переменные, входящие в lvalue не удаляются после окончания выполнения цикла и сохраняют последние присвоенные им значения. Однако, если последовательность sequence пустая, lvalue не будет присвоено никакое значение (таким образом, используя эти переменные без дополнительной проверки, Вы имеете шанс получить ошибку NameError).

Изменение перебираемой последовательности

Изменяя последовательность, элементы которой вы перебираете, будьте внимательны. Текущий элемент последовательности определяется значением внутреннего счетчика. Конец последовательности определяется по исключению IndexError при попытке получить очередной элемент. Таким образом, если в блоке suite1 Вы удалите текущий или один из пройденных элементов последовательности, следующий элемент будет пропущен.

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

for x in a[:]:
  if x < 0: a.remove(x)

Функции range() и xrange()

Если Вам необходимо перебирать последовательность чисел, то пригодится встроенная
функция range(). Она создает список, содержащий арифметическую прогрессию:
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Функция xrange работает аналогично, только вместо генерации списка создает объект типа xrange — его значения можно перебрать в цикле, но нельзя изменять

>>> type(range(2))
<type 'list'>
>>> type(xrange(2))
<type 'xrange'>

Инструкции break и continue, ветвь else в циклах

Инструкция break выходит из самого внутреннего вложенного цикла for или while. Инструкция continue продолжает выполнение цикла со следующей итерации.

Циклы могут иметь ветвь else, которая выполняется при “нормальном” выходе (исчерпание последовательности в цикле for, неудовлетворение условия в цикле while), без прерывания инструкцией break. Продемонстрируем ее использование на примере поиска простых чисел:

>>> for n in xrange(2, 10):
...   for x in xrange(2, n):
...     if n % x == 0:
...       print n, ’=’, x, ’*’, n/x
...       break
...     else:
...       print n, ’- простое число’
...
2 - простое число
3 - простое число
4 = 2 * 2
5 - простое число
6 = 2 * 3
7 - простое число
8 = 2 * 4
9 = 3 * 3

Функции

>>> def fib(n):

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

>>> def fib(n):
...   ’’’Выводит числа Фибоначчи в пределах заданного числа’’’
...   a, b = 0, 1
...   while b < n:
...     print b,
...     a, b = b, a+b

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

>>> q = range(5)
>>> def ch(l):
...   l.append('New one!')
...
>>> q
[0, 1, 2, 3, 4]
>>> ch(q)
>>> q
[0, 1, 2, 3, 4, 'New one!']

Инструкция return выходит из функции и возвращает значение. Без аргументов return используется для выхода из середины процедуры, в этом случае возвращается значение None.

Значения по умолчанию вычисляются в месте определения функции в области
видимости определения, так что

i = 5
def f(arg = i): print arg
i = 6
f()
выведет 5.

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

def f(a, l = []):
  l.append(a)
  return l
print f(1)
print f(2)
print f(3)

Результат выполнения будет следующий:

[1]
[1, 2]
[1, 2, 3]

Произвольный набор аргументов

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

def fprintf(file, format, *args):
  file.write(format % args)

Именованные аргументы

Функция может быть вызвана с использованием именованных аргументов (keyword
arguments) в виде ‘keyword = value’.

def example(formal, *arguments, **keywords):
  print "Обычные аргументы:", formal
  print ’-’*40
  for arg in arguments: print arg
  print ’-’*40
  for kw in keywords.keys():
    print kw, ’:’, keywords[kw]

Python lambda функции

lambda-функция делает то же самое, что и обычная функция.

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

>>> g = lambda x: x*2
>>> g(3)

Ввод и вывод данных в Python

Чтение и запись файлов

Встроенная функция open() возвращает объект-файл (file) и обычно используется с двумя аргументами: ‘open(filename, mode)’.

>>> f=open(’/tmp/workfile’, ’wb’)
>>> print f
<open file ’/tmp/workfile’, mode ’wb’ at 80a0960>

Первый аргумент — строка, содержащая имя файла, второй аргумент — строка, содер-жащая несколько символов, описывающих режим использования файла. Режим может быть ’r’, если файл открывается только для чтения, ’w’ — только для записи (су-ществующий файл будет перезаписан), и ’a’ — для дописывания в конец файла. В режиме ’r+’ файл открывается сразу для чтения и записи. Аргумент mode не является обязательным: если он опущен, подразумевается ’r’.

В Windows (а в некоторых случаях и в Macintosh) файлы по умолчанию открывают-ся в текстовом режиме — для того, чтобы открыть файл в двоичном режиме, необходимо к строке режима добавить ’b’. Следует помнить, что двоичные данные, такие как кар-тинки в формате JPEG и даже текст в UNICODE, при чтении из файла или записи в файл, открытый в текстовом режиме, будут испорчены! Лучший способ оградить себя от неприятностей — всегда открывать файлы в двоичном режиме, даже на тех плат-формах, где двоичный режим используется по умолчанию (возможно у Вас когда-нибудь возникнет желание запустить программу на другой платформе).

Модуль pickle

Если у Вас есть объект x и файловый объект f , открытый для записи, простейший способ сохранить объект потребует всего одну строку кода:

pickle.dump(x, f)

Так же просто можно восстановить объект (f — файловый объект, открытый для чте-ния):

x = pickle.load(f)

Встроенные функции Python

В язык Python входит множество функций, таких как map() и zip(), заметно упрощающих вычисления.

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

Списки

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

a = [’spam’, ’eggs’, 100, 1234]

Нумерация элементов списка аналогична строкам — первый элемент идет под номером 0.

Методы для работы со списками

append, pop и insert

Append добавляет в конец списка новый элемент.

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

>>> a.insert(2, -1)
[66.6, 333, -1, 333, 1, 1234.5, 333]

pop() возвращает последний элемент списка, удаляя его из списка.

index и count

Index позволит найти, в каком положении находится первый элемент с определенным значением.

Count может подсчитать количество таких элементов.

remove, sort, reverse

Использование списков

append и pop позволяют использовать списки в качестве стека:

>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]

Также легко использовать список в качестве очереди элементов — добавляя с помощью append и извлекая первый в очереди с помощью pop(0):

>>> queue = ["Eric", "John", "Michael"]
>>> queue.append("Terry") # Terry добавили в очередь
>>> queue.append("Graham") # Graham добавили в очередь
>>> queue.pop(0)
’Eric’
>>> queue.pop(0)
’John’
>>> queue
[’Michael’, ’Terry’, ’Graham’]

Срезы

Срезы нельзя делать из словарей и множеств или наборов.
Самое распространенное применение срезов в python — создания копии последовательности или ее части.
Рассмотрим срез как часть последовательности. Например, несколько срезов со списка:

>>> s = [1, 2, 3, 4, 6] #простой список
>>> s[:] #копия списка, часто очень полезно
[1, 2, 3, 4, 6]
>>> s[1:] # все элементы кроме первого
[2, 3, 4, 6]
>>> s[-3:] # последние 3 элемента
[3, 4, 6]
>>>s[2:-2] #откидываем первые и последние 2
[3]

Срезы могут быть с тремя параметрами:

s[::2] #парные элементы
[1, 3, 6]
>>> s[1:4:2] #элементы с первого по четвертый с шагом 2
[2, 4]

Все эти действия можно проворачивать со строками, кортежами и списками.

>>> "Hello Dolly!"[1::2]
'el ol!'

Как «развернуть» строку (кортеж, список):

>>> "God saw I was dog"[::-1]
'god saw I was doG'
>>> #отрицательный шаг может оказаться граблями, если не знать особенностей. 

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

>>> s = list(range(10)) #заполняем 0..9
>>> del s[3: -2: 2] #удаляем элементы между третьим и предпоследним с шагом 2
>>> s
[ 0, 1, 2, 4, 6, 8, 9]

Ещё можно вставлять элементы:
В варианте замены:

>>> s[2:5:2]=list("AF") #список был [0, 1, 2, 4, 6, 8, 9], мы заменили указанные элементы на [‘A’,’F’]
>>> #да, ещё в такой конструкции должны совпадать размеры, это легче понять попробовав
>>> s
[ 0, 1, 'A', 4, 'F', 8, 9]

Ну, или вариант вставки попроще:

>>> s[3:4] = ["4 was here"] # замена последовательного кусочка
>>> s
[ 0, 1, 'A', '4 was here', 'F', 8, 9]
>>> s[1:1] = ["after zero"] #или, просто, вставка
>>> s
[ 0, 'after zero', 1, 'A', '4 was here', 'F', 8, 9]

Можно создать класс, с которого можно будет делать срезы.
Переопределить __getitem__, __setitem__ и __delitem__.
С первого взгляда все кажется предельно простым, но если присмотреться, то __getitem__(self, key) – получает только один параметр, key, а у среза у нас может быть целых 3 числа… Все предельно просто: в случае, когда кто-то пытается срезать кусочек от нашего объекта, значением key функция получит объект типа slice:

>>> class MySliceble():
    def __getitem__(self, key):
        if isinstance(key, slice):
            return list(range(key.start, key.stop, key.step))
        else:
            raise Exception("Trying to access by index")
 
>>> my = MySliceble()
>>> my[2:10:1]
[2, 3, 4, 5, 6, 7, 8, 9]

Конечно, пример очень символический, но понять можно: у объекта класса slice есть три свойства: start, stop и step, соответствуют числам из скобок среза. Нужно быть внимательным, если число пропущена, то значение будет None, например [::] будет slice(None, None, None) а [:-3] будет slice(None, -3, None).
Замену/вставку и удаление срезов делаем по аналогии.

Кортежи — tuple

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

>>> t = 1, [’foo’, ’bar’]
>>> t
(1, [’foo’, ’bar’])
>>> t[1] = []
Traceback (innermost last):
File "<stdin>", line 1, in ?
TypeError: object doesn’t support item assignment
>>> t[1].append(’baz’)
>>> t(1, [’foo’, ’bar’, ’baz’])

Создание пустого кортежа

c = ()

Создание кортежа из одного элемента

c = (1, )

Словари — dictionaries

Лучше всего представлять словарь как неупорядоченное множество пар ключ: значение, с требованием уникальности ключей в пределах одного словаря. Пара фигурных скобок {} создает пустой словарь. Помещая список пар key: value, разделенных за-пятыми, в фигурные скобки, Вы задаете начальное содержимое словаря. В таком же виде записывается словарь при выводе.

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

>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'sape': 4139, 'guido': 4127, 'jack': 4098}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'guido': 4127, 'irv': 4127, 'jack': 4098}
>>> tel.keys()
['guido', 'irv', 'jack']
>>> 'guido' in tel
True

Модули в Python

Модуль — файл, содержащий определения и другие инструкции языка Python. Имя
файла образуется путем добавления к имени модуля суффикса (расширения) ‘.py’. В
пределах модуля, его имя доступно в глобальной переменной __name__.

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

Импортирование функций и переменных

Такой вариант инструкции import позволяет импортировать все имена, опре-деленные в модуле, кроме имен, начинающихся с символа подчеркивания (‘_’):
>>> from fibo import *

Начиная с версии Python 2.0, можно произвести подмену импортируемых имен при выполнении инструкции import:

import string as _string
from anydbm import open as dbopen

Функция dir()

Для выяснения имен, определенных в модуле, можно использовать встроенную функцию dir(). Она возвращает отсортированный список строк:

>>> import fibo, sys
>>> dir(fibo)
[’__name__’, ’fib’, ’fib2’]
>>> dir(sys)
[’__name__’, ’argv’, ’builtin_module_names’,
’copyright’, ’exit’, ’maxint’, ’modules’, ’path’,
’ps1’, ’ps2’, ’setprofile’, ’settrace’, ’stderr’,
’stdin’, ’stdout’, ’version’]

Без аргументов, dir() возвращает список имен, определенных в текущей области видимости:

Список, возвращаемый функцией dir() не содержит имена встроенных функций и переменных — они определены в стандартном модуле __builtin__:

Файл ‘__init__.py’ необходим для того, чтобы Python распознавал каталог, как со-держащий пакет — таким образом предотвращается маскировка полноценных модулей, расположенных далее в путях поиска, каталогами с распространенными именами (таки-ми как ‘string’). В простейшем случае, ‘__init__.py’ — пустой файл, но может содержать код инициализации пакета и/или устанавливать переменную __all__,

Инструкция import использует следующее соглашение: если в иницилизационном файле ‘__init__.py’ определен список с именем __all__, он исполь-зуется в качестве списка имен модулей, которые должны импортироваться при ис-пользовании ‘from package import *’. Поддержка этого списка в соответствии с текущим составом пакета возлагается на автора. Можно также не определять спи-сок __all__, если авторы не считают уместным импортирование *.

Обработка исключений

Следующий пример демонстрирует пользователю приглашение до тех пор, пока не будет введено целое число или выполнение не будет прервано (обычно Ctrl-C). Во втором случае генерируется исключение KeyboardInterrupt.

while 1:
  try:
    x = int(raw_input(
      "Введите целое число: "))
    break
  except ValueError:
    print "Вы ошиблись, попробуйте еще раз..."

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

... except (RuntimeError, TypeError, NameError):
...   pass

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

Классы в Python

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

Синтаксис определения класса

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

class class_name:
    some_instruction

Создание объектов — экземпляров класса

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

x = MyClass()

В приведенном примере создается “пустой” объект.

Пример создания класса с атрибутами и методами:

class MyClass:
  i = 12345
def f(x):
  return 'Привет всему миру!'

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

class MyClass:
    def __init__(self):
        self.data = []

Если для класса определен метод __init__(), то он автоматически вызывается при создании каждого экземпляра этого класса.

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

>>> class Complex:
...     def __init__(self, realpart, imagpart):
...         self.r = realpart
...         self.i = imagpart
...
>>> x = Complex(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)

Методы экземпляров класса

Обычно метод вызывают непосредственно:

x.f()

В нашем примере он вернет строку ’Привет всему миру!’. При этом совсем не обязательно вызывать метод прямо. x.f является объектом, и его можно сохранить для дальнейшего использования:

xf = x.f
while 1:
    print xf()

Особенность методов класса состоит в том, что что они получают объект, к которому принадлежат, в качестве первого аргумента. В нашем примере вызов x.f() полностью эквивалентен MyClass.f(x). В общем, вызов метода, привязанного к объекту, со списком из n аргументов полностью эквивалентен вызову соответствующего не привязанного метода-функции со списком аргументов, полученным добавлением объекта перед первым аргументом.

Наследование

Определение производного класса с именем ClassB выглядит следующим образом:

class ClassB(ClassA):
...

Базовый класс (ClassA) должен быть определен в области видимости, в которой находится определение производного класса ClassB. Вместо имени базового класса можно использовать выражение.

Например, если базовый класс определен в другом модуле:

class ClassB(ModulA.ClassA):

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

>>> class ClassA:
...   a = 'A'
...   b = 'B'
...   def Print_A(self):
...     print a
...   def Print_B(self):
...     print self.b
...   def Print_Both(self):
...     pring
...   def PrintBoth(self):
...     print 'Printing A'
...     self.Print_A()
...     print 'Printing B'
...     self.Print_B()
...
>>> a = 'aaa'
>>> cc = ClassA()
>>> cc.Print_A()
aaa
>>> cc.Print_B()
B
>>> cc.PrintBoth()
Printing A
aaa
Printing B
B
>>> class ClassB(ClassA):
...   def Print_A(self):
...     print self.a
...
>>> ccc = ClassB()
>>> ccc.PrintBoth()
Printing A
A
Printing B
B

Переопределяя метод в производном классе, Вы можете также захотеть вызвать метод базового класса с тем же именем. Это можно сделать: просто вызовите метод, явно указав имя класса:

>>> class ClassC(ClassA):
...   def Print_A(self):
...     print 'Print using old method from ClassA'
...     ClassA.Print_A(self)
...
>>> c = ClassC()
>>> c.PrintBoth()
Printing A
Print using old method from ClassA
aaa
Printing B
B

Множественное наследование в Python

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

>>> class ClassD(ClassB, ClassA):
...   "Checking inheritance"
...
...
>>> d = ClassD()
>>> d.PrintBoth()
Printing A
A
Printing B
B

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

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

Частные атрибуты

>>> class clA:
...   __privateA = 'aaa'
...   def prn(s):
...     print s.__privateA
...
>>> class clB(clA):
...   __privateA = 'bbb'
...
>>> A = clB()
>>> A.prn()
aaa
>>> A.__privateA
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: clB instance has no attribute '__privateA'

>>> dir(A)
['__doc__', '__module__', '_clA__privateA', '_clB__privateA', 'prn']
>>> A._clB__privateA
'bbb'
>>>

Практические примеры

Как убрать из строки все символы, кроме цифр, в Python?

>>> import re
>>> re.sub("[^0-9]", "", "sdkjh987978asd098as0980a98sd")
'987978098098098'

Список источников

Всё, что Вы хотели знать о слайсах

Язык программирования Python — подробно для начинающих: 3 комментария

  1. Спасибо. Недавно как раз начал изучать python с книгой Саммерсфилда, ваша заметка тоже мне помогла узнать много нового.
    З.Ы. Было бы интересно увидеть заметку о различиях в python 2 и 3.

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

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