Отличие python метода методы - В чем разница между функцией, несвязанным методом и связанным методом? Чтение и запись файлов. Операции и операнды

Обзор различий синтаксиса python2 и python3.

Print - функция

Оператор print был заменён функцией print(), с именованными аргументами для замены большей части синтаксиса старого оператора print. Примеры:

Python2 : print "The answer is" , 2 * 2 Python3 : print ("The answer is" , 2 * 2 ) Python2 : print x , # Запятая в конце подавляет перевод строки Python3 : print (x , end = " " ) # Добавляет пробел вместо перевода строки Python2 : print # Печатает перевод строки Python3 : print () # Нужно вызвать функцию! Python2 : print >> sys . stderr , "fatal error" Python3 : print ("fatal error" , file = sys . stderr ) Python2 : print (x , y ) # Печатает repr((x, y)) Python3 : print ((x , y )) # Не путать с print(x, y)!

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

>>> print ("There are <" , 2 ** 32 , "> possibilities!" , sep = "" ) There are <4294967296> possibilities!

Функция print() не поддерживает особенность "программный пробел" старого оператора print. Например, в Python 2, print "A\n", "B" напечатает "A\nB\n"; но в Python 3, print("A\n", "B") напечатает "A\n B\n".

Отображения и итераторы вместо списков

Некоторые хорошо известные методы не возвращают в Python 3:

  • Методы словарей dict.keys(), dict.items() и dict.values() возвращают "отображения" вместо списков. Например, больше не работает: k = d.keys(); k.sort(). Используйте k = sorted(d).
  • Соответственно, методы dict.iterkeys(), dict.iteritems() и dict.itervalues() более не поддерживаются.
  • map() и filter() возвращают итераторы. Если вам действительно нужен список, быстрым исправлением станет list(map(...)), но часто лучшим исправлением будет использование генераторов списков (особенно когда оригинальный код использует лямбда-выражения), либо переписать код так, чтобы ему не нужен был список как таковой. Особенно сложно, что map() вызывает побочные эффекты функции; правильное преобразование заключается в использовании цикла (создание списка просто расточительно).
  • range() теперь ведёт себя как xrange(), но работает со значениями любого размера. xrange() больше не существует.
  • zip() возвращает итератор.

Операторы сравнения

Python 3 упростил правила для операторов сравнения:

Операторы сравнения (<, <=, >=, >) поднимают исключение TypeError, когда операнды не упорядочиваемы. Таким образом, выражения типа 1 < "", 0 > None или len <= len более не разрешены, и, например, None < None поднимает TypeError, а не возвращает False. Следствием является то, что сортировка списка с разными типами данных больше не имеет смысла - все элементы должны быть сравнимы друг с другом. Обратите внимание, что это не относится к операторам == и!=: объекты различных несравнимых типов всегда неравны друг другу.

builtin.sorted() и list.sort() больше не принимают аргумент cmp, обеспечивающий функцию сравнения. Вместо этого используйте аргумент key. Аргументы key и reverse теперь "keyword-only".

Функция cmp() должна рассматриваться как устаревшая, и специальный метод __cmp__() в Python 3 не поддерживается. Используйте __lt__() для сортировки, __eq__() с __hash__() для сравнения. (Если вам действительно нужна функциональность cmp(), вы можете использовать выражение (a > b) - (a < b) в качестве эквивалента для cmp(a, b).)

Целые числа

  • PEP 0237: long переименован в int.
  • PEP 0238: Выражение вида 1/2 возвращает float. Используйте 1//2 для отсечения дробной части. (Этот синтаксис существует с Python 2.2)
  • Константа sys.maxint была удалена, с тех пор, как более не существует предела значения целых чисел. Однако, sys.maxsize может быть использован как число, большее любого практического индекса списка или строки. sys.maxsize соответствует "естественному" размеру целого и, как правило, имеет такое же значение, как sys.maxint на той же платформе (при условии одних и те же параметров сборки).
  • repr() от длинного целого числа не включает более завершающий символ L, так что код, который безусловно отрезает этот символ, будет отрезать вместо этого последнюю цифру. (Используйте str() вместо этого.)
  • Восьмеричные литералы более не имеют формы вида 0720; используйте 0o720.

Текст, Unicode и 8-битные строки

Все, что вы знали о бинарных данных и Unicode, изменилось.

Python 3 использует понятия текста и (бинарных) данных вместо строк Unicode и 8-битных строк. Весь текст - Unicode; Однако кодированные Unicode строки представлены ​​в виде двоичных данных. Тип, используемый для хранения текста является , тип, используемый для хранения данных - . Самое большое различие с python 2.x является то, что любая попытка комбинировать текст и данные в Python 3.0 поднимает TypeError, в то время как если бы вы смешивали Unicode и 8-битные строки в Python 2.x, это будет работать, если 8-битная строка содержала только 7-битные (ASCII) символы, но вы получите UnicodeDecodeError, если она содержит не-ASCII символы. Такое поведение вызывало многочисленные скорбные лица на протяжении многих лет.

Как следствие этого изменения в философии, значительная часть кода, который использует Unicode, кодировки или бинарные данные, скорее всего, должна измениться. Это изменения к лучшему, так как в python 2.x были многочисленные ошибки, имеющие отношение к смешиванию закодированного и декодированного текста. Чтобы быть подготовленным к этому, в Python 2.x следует начать использовать Unicode для всего незакодированного текста, и str только для бинарных или закодированных данных. Затем инструмент 2to3 будет делать большую часть работы за вас.

Вы можете больше не использовать литерал u"..." для текста Unicode. Тем не менее, вы должны использовать литерал b"..." для бинарных данных.

Так как str и bytes не могут быть смешаны, вы всегда должны их явно преобразовывать. Используйте str.encode(), чтобы перейти от str к bytes и bytes.decode(), чтобы перейти от bytes к str. Вы также можете использовать bytes(s, encoding=...) и str(b, encoding=...), соответственно.

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

Все обратные косые черты в "сырых" строковых литералах интерпретируются буквально. Это означает, что "\U" и "\u" в сырых строках не рассматриваются особо. Например, r"\u20ac" это строка из 6 символов в Python 3.0, в то время как в 2.6, ur"\u20ac" был один символ "евро". (Конечно, это изменение влияет только на сырые строковые литералы).

Встроенный абстрактный тип basestring был удален. Используйте str вместо него. str и bytes не имеют достаточно общей функциональности, чтобы оправдать общий базовый класс. Инструмент 2to3 (см. ниже) заменяет каждое вхождение basestring на str.

PEP 3138: repr() для строки больше не экранирует символы, не входящие в набор ASCII. Однако, он по-прежнему экранирует управляющие символы

PEP 3120: Кодировка исходного кода по умолчанию теперь UTF-8.

PEP 3131: не-ASCII символы разрешены в идентификаторах. (Тем не менее, стандартная библиотека остается ASCII, за исключением имен авторов в комментариях.)

Модули StringIO и cStringIO удалены. Вместо этого, импортируйте модуль io и используйте io.StringIO или io.BytesIO для текста и данных соответственно.

Обзор изменений синтаксиса

Этот раздел дает краткий обзор каждого синтаксического изменения Python 3.0.

Новый синтаксис

PEP 3107: аннотации для аргументов функции и возвращаемых значений.

>>> def foo (a : "x" , b : 5 + 6 , c : list ) -> max (2 , 9 ): ... pass >>> foo . __annotations__ {"a": "x", "b": 11, "c": , "return": 9}

PEP 3102: Keyword-only аргументы.

PEP 3104: nonlocal. Переменная во внешней (но не глобальной) области видимости.

>>> def outer (): ... x = 1 ... def inner (): ... x = 2 ... print ("inner:" , x ) ... inner () ... print ("outer:" , x ) ... >>> outer () inner: 2 outer: 1 >>> def outer (): ... x = 1 ... def inner (): ... nonlocal x ... x = 2 ... print ("inner:" , x ) ... inner () ... print ("outer:" , x ) ... >>> outer () inner: 2 outer: 2

PEP 3132: Extended Iterable Unpacking

>>> (a , * rest , b ) = range (5 ) >>> a 0 >>> rest >>> b 4

Генераторы словарей: {k: v for k, v in stuff} (то же самое, что и dict(stuff))

Литералы множеств (например, {1, 2}). Заметьте, что {} - это пустой словарь. Используйте set() для пустых множеств. Генераторы множеств: {x for x in stuff}

Новые восьмеричные литералы, например 0o720, вместо старых (0720).

Новые двоичные литералы, например 0b1010. Новая встроенная функция, bin().

Изменённый синтаксис

PEP 3109 and PEP 3134: новый синтаксис выражения raise: raise ].

"as" и "with" зарезервированные слова.

"True" и "False" и "None" - зарезервированные слова.

Изменено "except exc, var" на "except exc as var".

PEP 3115: Новый синтаксис для метаклассов. Вместо:

class C : __metaclass__ = M ...

Вы должны использовать:

class C (metaclass = M ): ...

Переменная __metaclass__ более не поддерживается.

Генераторы списков больше не поддерживают синтаксическую форму [... for var in item1, item2, ...]. Используйте [... for var in (item1, item2, ...)].

Удаленный синтаксис

PEP 3113: распаковка кортежей в параметрах удалена. Вы больше не можете писать

def foo (a , (b , c )): ... def foo (a , b_c ): b , c = b_c ...

Удалены обратные кавычки (backtick). Используйте repr().

Удалено <>. Используйте!=.

exec - функция. Перестала быть зарезервированным словом.

from module import * запрещено использовать внутри функций.

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

PEP 3135: Новый super(). Теперь вы можете вызывать super() без аргументов и (при условии, что это метод экземпляра, определенный внутри определении класса) класс и экземпляр будут автоматически выбраны. С аргументами, поведение super() остается без изменений.

PEP 3111: raw_input() переименован в input(). Вместо input() в Python 2, вы можете использовать eval(input()).

Добавлена функция next(), вызывающая метод __next__() объекта.

Перемещен intern() в sys.intern().

Удалено: apply(). Вместо apply(f, args) используйте f(*args).

Удалено: callable(). Вместо callable(f) используйте hasattr(f, "__call__"). Функция operator.isCallable() также удалена.

Удалено: coerce().

Удалено: execfile(). Вместо execfile(fn) используйте exec(open(fn).read()).

Удалено: file. Используйте open().

Перемещено: reduce() в functools.reduce()

Перемещено: reload() в imp.reload().

Удалено: dict.has_key(). Используйте оператор in.

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

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

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

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

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

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

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

Отступы

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

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

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

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

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

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

Строки в 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)’.)

Также может быть полезна функция 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 функции

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

Циклы

Цикл While

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

While expr: suite1

Инструкция 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

Выражение 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)

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

>>> type(range(2)) >>> type(xrange(2))

Инструкции 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 >>> ch(q) >>> q

Инструкция 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)

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

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

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

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

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

Первый аргумент - строка, содержащая имя файла, второй аргумент - строка, содер-жащая несколько символов, описывающих режим использования файла. Режим может быть ’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)

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

index и count

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

remove, sort, reverse

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

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

>>> stack = >>> stack.append(6) >>> stack.append(7) >>> stack >>> stack.pop() 7 >>> stack

Также легко использовать список в качестве очереди элементов — добавляя с помощью 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 = #простой список >>> s[:] #копия списка, часто очень полезно >>> s # все элементы кроме первого >>> s[-3:] # последние 3 элемента >>>s #откидываем первые и последние 2

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

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

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

>>> "Hello Dolly!" "el ol!"

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

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

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

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

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

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

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

>>> s = ["4 was here"] # замена последовательного кусочка >>> s [ 0, 1, "A", "4 was here", "F", 8, 9] >>> s = ["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

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

Кортежи — tuple

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

>>> t = 1, [’foo’, ’bar’] >>> t (1, [’foo’, ’bar’]) >>> t = Traceback (innermost last): File "", line 1, in ? TypeError: object doesn’t support item assignment >>> t.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 является объектом, и его можно сохранить для дальнейшего использования:

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"

Одна интересная вещь, которую я видел сегодня, это то, что когда я назначаю функцию члену класса, она становится несвязанным методом. Такие как:

Class Test(object): @classmethod def initialize_class(cls): def print_string(self, str): print(str) # Here if I do print(print_string), I see a function cls.print_proc = print_string # Here if I do print(cls.print_proc), I see an unbound method; so if I # get a Test object o, I can call o.print_proc("Hello")

2018-12-04T00:00Z

довольно сложно понять

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

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

>>> f = A.__dict__["f1"] >>> f(1) 1

Регулярный TypeError возникает в случае возникновения проблем с количеством параметров:

>>> ", line 1, in TypeError: f1() takes exactly 1 argument (0 given)

Теперь методы. Методы - это функции с небольшим количеством специй. Здесь есть дескрипторы. Как описано в модели данных , A.f1 и A().f1 переводятся в A.__dict__["f1"].__get__(None, A) и type(a).__dict__["f1"].__get__(a, type(a)) соответственно. И результаты этих __get__ отличаются от функции raw f1 . Эти объекты являются обертками вокруг исходного f1 и содержат некоторую дополнительную логику.

В случае unbound method эта логика включает проверку того, является ли первый аргумент экземпляром A:

>>> f = A.f1 >>> f() Traceback (most recent call last): File "", line 1, in TypeError: unbound method f1() must be called with A instance as first argument (got nothing instead) >>> f(1) Traceback (most recent call last): File "", line 1, in TypeError: unbound method f1() must be called with A instance as first argument (got int instance instead)

Если эта проверка завершается успешно, она выполняет оригинальный f1 с этим экземпляром в качестве первого аргумента:

>>> f(A()) <__main__.A object at 0x800f238d0>

Обратите внимание, что атрибут im_self равен None:

>>> f.im_self is None True

В случае bound method эта логика немедленно поставляет исходный f1 с экземпляром A который был создан (этот экземпляр фактически хранится в im_self):

>>> f = A().f1 >>> f.im_self <__main__.A object at 0x800f23950> >>> f() <__main__.A object at 0x800f23950>

Таким образом, bound означает, что базовая функция привязана к некоторому экземпляру. unbound означает, что он все еще связан, но только с классом.

2018-12-11T00:00Z

Моя интерпретация такова.

Фрагменты Function класса:

Class Function(object): . . . def __get__(self, obj, objtype=None): "Simulate func_descr_get() in Objects/funcobject.c" if obj is None: return self return types.MethodType(self, obj)

Class Function(object): . . . def __get__(self, obj, objtype=None): "Simulate func_descr_get() in Objects/funcobject.c" return types.MethodType(self, obj, objtype)

  1. Если функция вызывается без класса или экземпляра, это простая функция.
  2. Если функция вызывается из класса или экземпляра, ее __get__ вызывается для извлечения завернутой функции:
    а. Bx совпадает с B.__dict__["x"].__get__(None, B) . В Python 3 это возвращает обычную функцию. В Python 2 это возвращает несвязанную функцию.

    б. bx аналогичен type(b).__dict__["x"].__get__(b, type(b) . Это вернет связанный метод как в Python 2, так и в Python 3, что означает, что self будет неявно передан в качестве первого аргумента.