Как устроен Python. Как устроен Python. Харрисон. Харрисон Мэтт
Скачать 5.41 Mb.
|
Рис. 11.1. Вызов метода для строки. Метод не изменяет саму строку, потому что строки неизменяемы. Вместо этого метод возвращает новую строку Строки и методы 87 В следующем примере метод .capitalize вызывается для переменной, указывающей на строку, и для строкового литерала. Обратите внимание: объект, для которого вызывается метод, при этом не изменяется. Так как строки неизменяемы, результатом метода является новый объект со значением, записанным с прописной буквы: >>> name = 'matt' # вызывается для переменной >>> correct = name.capitalize() >>> print(correct) Matt Обратите внимание: name при этом не изменяется: >>> print(name) matt Метод .capitalize не обязательно вызывать для переменной. Его также можно вызвать прямо для строкового литерала: >>> print('fred'.capitalize()) Fred В Python методы и функции являются полноправными объектами. Как упоминалось ранее, в Python вообще нет ничего, кроме объектов. Если опустить круглые скобки, Python не выдаст сообщения об ошибке, а вы- ведет ссылку на метод, который является объектом: >>> print('fred'.capitalize) Существование методов и функций как полноправных объектов позво- ляет использовать такие нетривиальные возможности, как замыкания и декораторы (они рассматриваются в моем учебнике Python промежу- точного уровня). 88 Глава 11. Строки и методы ПРИМЕЧАНИЕ А у целых чисел и чисел с плавающей точкой тоже есть методы? Да, еще раз повторю: в Python нет ничего, кроме объектов, и у объектов есть методы. В этом легко убедиться, вызвав dir для целого числа (или переменной, в которой хранится целое число): >>> dir(4) ['__abs__', '__add__', '__and__', '__class__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'conjugate', 'denominator', 'imag', 'numerator', 'real'] Вызов метода для числа несколько усложняется использованием точки для обозначения вызова метода. Так как точка часто встречается в числах с плавающей точкой, ее использование для вызова методов для чисел может привести Python в замешательство. Например, метод .conjugate возвращает комплексное сопряжение цело- го числа. Но при попытке вызвать его для целого числа вы получите ошибку: >>> 5.conjugate() Traceback (most recent call last): 5.conjugate() ^ SyntaxError: invalid syntax Одно из возможных решений — заключить число в круглые скобки: >>> (5).conjugate() 5 Также можно присвоить переменную 5 и вызвать метод для переменной: >>> five = 5 >>> five.conjugate() 5 Впрочем, на практике вызов методов для чисел встречается довольно редко. 11.2. endswith 89 11.1. Основные строковые методы Некоторые методы строк часто используются в программах и обнару- живаются в стороннем коде. Информацию о других можно найти при помощи dir и help (или электронной документации). 11.2. endswith Допустим, у вас имеется переменная с именем файла и вы хотите про- верить расширение. Задача легко решается методом .endswith : >>> xl = 'Oct2000.xls' >>> xl.endswith('.xls') True >>> xl.endswith('.xlsx') False ПРИМЕЧАНИЕ Обратите внимание: при вызове метода вы должны были передать пара- метр (или аргумент) 'xls' . У методов имеется сигнатура — этот пугающий термин означает, что они должны вызываться с правильным количеством (и типами) параметров. Для метода .endswith вполне логично, что, если вы хотите узнать, кончается ли строка другой строкой, нужно сообщить Python, какое именно завершение нужно проверить. Для этого методу передается строка-завершитель. СОВЕТ И снова всю информацию такого рода можно легко найти при помощи help В документации должно быть указано, какие параметры являются обязатель- ными, а также должны быть перечислены все необязательные параметры. Справка для endswith выглядит так: >>> help(xl.endswith) Help on built-in function endswith: endswith(...) S.endswith(suffix[, start[, end]]) -> bool Return True if S ends with the specified 90 Глава 11. Строки и методы suffix, False otherwise. With optional start, test S beginning at that position. With optional end, stop comparing S at that position. suffix can also be a tuple of strings to try 1 Обратите внимание на строку S.endswith(suffix[, start[, end]]) -> bool S представляет строку (экземпляр), для которой вызывается метод; в нашем случае это переменная xl . Имя метода — .endswith . В круглые скобки ( ) заключены параметры. Обязательным параметром является suffix . Метод .endswith сообщит об ошибке, если этот параметр не будет передан при вызове: >>> xl.endswith() Traceback (most recent call last): File " TypeError: endswith() takes at least 1 argument (0 given) Параметры в квадратных скобках [ ] являются необязательными. В данном случае параметры start и end позволяют проверить только часть строки. На- пример, если вы хотите убедиться в том, что часть строки с 0 и до 3 символов завершается символами « Oct », это можно сделать так: >>> xl.endswith('Oct', 0, 3) True У строк также имеется парный метод .startswith , так что, если вы захотите узнать, начинается ли строка с 'Oct' , это делается так: >>> xl.startswith('Oct') True 1 Вернуть True , если S заканчивается suffix , в противном случае — False . При дополни- тельном запуске проверка S начинается с этой позиции. С необязательным параметром end прекратите сравнение S в этом положении. suffix также может быть кортежем строк. 11.4. format 91 11.3. find Метод .find предназначен для поиска подстрок в других строках. Он воз- вращает индекс (смещение, начинающееся с 0) совпадающей подстроки. Если подстрока не найдена, метод возвращает −1: >>> word = 'grateful' # 0 is g, 1 is r, 2 is a >>> word.find('ate') 2 >>> word.find('great') -1 11.4. format Метод format позволяет легко создавать новые строки, объединяя суще- ствующие переменные. Этот метод рассматривался в главе 9: >>> print('name: {}, age: {}'.\ ... format('Matt', 10)) name: Matt, age: 10 ПРИМЕЧАНИЕ В приведенном примере функция print занимает две строки. Последователь- ность символов .\ сообщает Python, что на следующей строке находится продолжение. Если открыта левая круглая скобка ( , вы также можете раз- мещать аргументы в нескольких строках без \ : >>> print("word". ... find('ord')) 1 >>> print("word".find( ... 'ord')) 1 Чтобы код лучше читался, строки продолжения снабжаются отступом. От- ступ из четырех пробелов сообщает всем читателям кода, что вторая строка является продолжением предыдущей команды: 92 Глава 11. Строки и методы >>> print("word".\ ... find('ord')) 1 >>> print("word".find( ... 'ord')) 1 Зачем разбивать код, который мог бы поместиться в одной строке, на не- сколько строк? Чаще всего это делается при использовании стандартов оформления кода, требующих, чтобы длина строки не превышала 80 сим- волов. Если метод получает несколько аргументов, выдержать ограничение в 80 символов может быть непросто. (Для Python длина строки не важна, но читатели вашего кода — другое дело.) На практике каждый аргумент метода нередко размещается в отдельной строке: >>> print('{} {} {} {} {}'.format( ... 'hello', ... 'to', ... 'you', ... 'and', ... 'you' ... )) hello to you and you 11.5. join Нередко имеется список (см. далее в книге), и вы хотите что-то вставить между существующими элементами. Метод .join создает новую строку из последовательности, вставляя строку между каждой парой элементов списка: >>> ', '.join(['1','2','3']) '1, 2, 3' СОВЕТ В большинстве интерпретаторов Python .join работает быстрее, чем много- кратная конкатенация с использованием оператора + . Приведенная идиома является стандартной. 11.8. strip 93 11.6. lower Метод .lower возвращает копию строки, преобразованную к нижнему регистру. Такое преобразование часто бывает полезно для проверки совпадения ввода с некоторой строкой. Например, одни программы за- писывают расширения файлов в верхнем регистре, другие — нет. Если вы хотите проверить, имеет ли файл расширение TXT или txt , это можно сделать так: >>> fname = 'readme.txt' >>> fname.endswith('txt') or fname.endswith('TXT') True Версия, более традиционная для Python, выглядит так: >>> fname.lower().endswith('txt') True 11.7. startswith Метод .startswith аналогичен .endswith , но он проверяет, начинается ли строка с другой строки: >>> 'Book'.startswith('B') True >>> 'Book'.startswith('b') False 11.8. strip Метод .strip возвращает новую строку, из которой удалены начальные и конечные пропуски (пробелы, табуляции, символы новой строки). На- пример, это может быть полезно для нормализации или разбора данных, введенных пользователем (или загруженных из интернета). >>> ' hello there '.strip() 'hello there' 94 Глава 11. Строки и методы Обратите внимание: из строки были удалены три начальных пробела и два пробела в конце. При этом два пробела между словами остались на своих местах. Если вам нужно удалить только начальные или конечные пропуски, эти задачи решаются методами lstrip и rstrip соответственно. 11.9. upper Метод .upper аналогичен .lower . Он возвращает копию строки, в которой все буквы преобразованы к верхнему регистру: >>> 'yell'.upper() 'YELL' 11.10. Другие методы У строк есть и другие методы, но они используются реже. Познакомьтесь с ними самостоятельно — прочитайте документацию и опробуйте на практике. В приложении приведен полный список этих методов. ПРИМЕЧАНИЕ Часть STRINGMETHODS в разделе справки из REPL содержит документацию по всем строковым методам, а также ряд примеров. 11.11. Итоги Эта глава была посвящена методам. Методы всегда вызываются с ука- занием объекта и точки перед именем метода. Также были рассмотрены наиболее типичные методы для строк. Следует помнить, что строки являются неизменяемыми. Если вы захотите изменить значение строки, для этого необходимо создать новую строку. 11.12. Упражнения 1. Создайте строку school с названием вашего учебного заведения. Просмотрите методы, доступные для этой строки. Воспользуйтесь функцией help для просмотра документации. 11.12. Упражнения 95 2. Создайте строку country со значением 'usa' . Создайте новую стро- ку correct_country со значением, преобразованным к верхнему ре- гистру, с использованием строкового метода. 3. Создайте строку filename со значением 'hello.py' . Проверьте, завер- шается ли имя файла суффиксом '.java' . Определите индекс под- строки 'py' . Проверьте, начинается ли строка с подстроки 'world' 4. Откройте REPL. Войдите в режим справочной информации и про- смотрите раздел STRINGMETHODS 12 Комментарии, логические значения и None В этой главе рассматриваются комментарии, логические значения и None Комментарии делают ваш код более понятным. Логические значения и тип None очень часто используются в коде Python. 12.1. Комментарии Комментарии не являются типом, потому что Python их игнорирует. Они должны что-то напомнить или пояснить программисту. Существу- ют разные мнения по поводу того, как нужно писать комментарии, их цели и полезности. Спектр мнений широк: от тех, кто против любых комментариев, до тех, кто комментирует почти каждую строку кода. Если вы участвуете в проекте, старайтесь соблюдать принятую в нем схему комментирования. Как правило, хороший комментарий должен объяснять почему, а не как (для ответа на вопрос как должно быть до- статочного самого кода). Чтобы создать комментарий в Python, начните строку с символа # . Все, что следует после этого символа, игнорируется: >>> # This line is ignored by Python Также комментарий может располагаться в конце строки: >>> num = 3.14 # PI 12.2. Логические значения 97 СОВЕТ Комментарии также используются для временной блокировки кода в про- цессе редактирования. Если ваш редактор поддерживает такую возможность, иногда бывает проще закомментировать код вместо того, чтобы удалять его полностью. Тем не менее перед тем, как передавать код для распространения, закоммен- тированные участки лучше удалить. В других языках поддерживаются многострочные комментарии, но в Python их нет. Единственный способ создать комментарий из несколь- ких строк — начинать каждую строку с # СОВЕТ Возможно, у вас появилась соблазнительная мысль создать комментарий из нескольких строк при помощи строки, заключенной в тройные кавычки. Такие конструкции получаются уродливыми и непонятными, не исполь- зуйте их. 12.2. Логические значения Логические значения представляют понятия «истина» ( True ) и «ложь» ( False ). Вы уже видели их в приведенных ранее примерах кода — напри- мер, в результате .startswith : >>> 'bar'.startswith('b') True Такие значения можно присваивать переменным: >>> a = True >>> b = False ПРИМЕЧАНИЕ В языке Python логические значения относятся к классу bool : >>> type(True) 98 Глава 12. Комментарии, логические значения и None Бывает полезно преобразовывать другие типы к логическим значениям. В языке Python это можно сделать при помощи класса bool . Впрочем, обычно прямые преобразования типов оказываются излишними из-за неявного преобразования, которое выполняет Python при проверке ус- ловных конструкций. При обработке условий это преобразование будет выполнено за вас. В терминологии Python нередко приходится слышать о «квазиистинном» или «квазиложном» поведении объектов — это означает, что нелогиче- ские типы могут неявно вести себя так, словно являются логическими. Если вы не уверены в том, как себя поведет ваш тип, выполните явное преобразование с использованием класса bool Для строк пустая строка обладает «квазиложным» поведением, тогда как непустые значения интерпретируются как True : >>> bool('') False >>> bool('0') # Строка содержит 0 True Так как непустая строка обладает квазиистинным поведением, вы мо- жете проверить, содержит ли строка какие-либо данные. В следующем фрагменте значение name задается в коде, но представьте, что оно должно вводиться пользователем: >>> name = 'Paul' >>> if name: ... print("The name is {}".format(name)) ... else: ... print("Name is missing") The name is Paul Необязательно проверять длину name . Не делайте так: >>> if len(name) > 0: ... print("The name is {}".format(name)) И так тоже поступать не нужно: >>> if bool(name): ... print("The name is {}".format(name)) 12.2. Логические значения 99 потому что Python вычислит содержимое команды if и преобразует его в логическое значение за вас. Поскольку непустая строка интерпретиру- ется как True , достаточно использовать конструкцию вида >>> if name: ... print("The name is {}".format(name)) ПРИМЕЧАНИЕ Встроенные типы int , float , str и bool являются классами. Хотя из-за регистра символов (нижнего) они похожи на функции, на самом деле это классы. В этом легко убедиться вызовом help(str) : >>> help(str) Help on class str in module builtins: class str(object) | str(object='') -> str | str(bytes_or_buffer[, encoding[, errors]]) -> str | Здесь проявляется небольшая непоследовательность языка Python: классы, определяемые пользователем, обычно подчиняются правилам PEP8, которые рекомендуют «верблюжий» регистр в именах классов. Для чисел ноль интерпретируется как False , тогда как другие числа об- ладают поведением True : >>> bool(0) False >>> bool(4) True Хотя явное преобразование функцией bool доступно, обычно оно излиш- не, потому что переменные неявно преобразуются в логические значения при использовании в условных командах. Например, типы-контейнеры (такие, как списки и словари), не содержащие элементов, обладают «ква- зиложным» поведением. С другой стороны, при появлении элементов они интерпретируются как «квазиистинные». СОВЕТ Будьте внимательны при разборе содержимого, которое должно быть пре- образовано в логические значения. Непустые строки интерпретируются как 100 Глава 12. Комментарии, логические значения и None True . Например, неожиданный сюрприз может преподнести строка 'False' , которая интерпретируется как True : >>> bool('False') True Ниже приведена таблица квазиистинных и квазиложных значений. Квазиистинность Квазиложность True False Большинство объектов None 1 0 3.2 0.0 [1, 2] [] (пустой список) {'a': 1, 'b': 2} {} (пустой словарь) 'string' "" (пустая строка) 'False' '0' СОВЕТ Не проверяйте логические значения, чтобы узнать, равны ли они True . Если у вас имеется переменная done , содержащая логическое значение, достаточно следующей конструкции: if done: # ... С другой стороны, следующая проверка будет излишней: if done == True: # ... Как и эта проверка: if bool(done): # ... Аналогичным образом, если у вас имеется список и вам потребуется вы- полнить разные действия для пустого и непустого списка, достаточно будет следующего фрагмента: 12.3. None 101 members = [] if members: # Действия, если members # содержит значения else: # Список members пуст А следующая проверка будет избыточной. Не нужно проверять квазиистин- ность списка по его длине: if len(members) > 0: # Действия, если members # содержит значения else: # Список members пуст |