Программирование на Python 3. Руководство издательство СимволПлюс
Скачать 3.74 Mb.
|
95 s.maketrans() Парный метод для str.translate(); подробности приводятся в тексте s.partition (t) Возвращает кортеж из трех строк – часть строки s перед са мым первым (крайним слева) вхождением подстроки t, t и часть строки s после подстроки t; если подстрока t в строке s отсутствует, возвращаются строка s и две пустые строки. Для деления строки по самому последнему (крайнему справа) вхождению подстроки t, используйте метод str.rpartition() s.replace (t, u, n) Возвращает копию строки s, в которой каждое (но не более n, если этот аргумент определен) вхождение подстроки t заме щается подстрокой u s.split(t, n) Возвращает список строк, выполняя разбиение строки s не более чем n раз по подстроке t. Если число n не задано, раз биение выполняется по всем найденным подстрокам t. Если подстрока t не задана, разбиение выполняется по пробель ным символам. Для выполнения разбиения строки, начиная с правого края, используйте метод str.rsplit – этот метод имеет смысл применять, когда задано число разбиений n, ко торое меньше максимального числа возможных разбиений s.splitlines (f) Возвращает список строк, выполняя разбиение строки s по символам перевода строки, удаляя их, если в аргументе f не задано значение True s.startswith (x, start, end) Возвращает True, если строка s (или срез строки s[start:end]) начинается подстрокой x или любой из строк, если x – кор теж; в противном случае возвращает False. Смотрите также метод str.endswith() s.strip(chars) Возвращает копию строки s, из которой удалены начальные и завершающие пробельные символы (или символы, входя щие в строку chars). Метод str.lstrip() выполняет удаление только в начале строки, а метод str.rstrip() – только в конце s.swapcase() Возвращает копию строки s, в которой все символы верхнего регистра преобразованы в символы нижнего регистра, а все символы нижнего регистра – в символы верхнего регистра; смотрите также методы str.lower() и str.upper() s.title() Возвращает копию строки s, в которой первые символы ка ждого слова преобразованы в символы верхнего регистра, а все остальные символы – в символы нижнего регистра; смотрите также метод str.istitle() s.translate() Парный метод для str.maketrans(); подробности приводятся в тексте s.upper() Возвращает копию строки s, в которой все символы приведе ны к верхнему регистру; смотрите также метод str.lower() s.zfill(w) Возвращает копию строки s, которая, если ее длина меньше величины w, дополняется слева нулями до длины w Синтаксис Описание 96 Глава 2. Типы данных Метод str.join() может также использоваться в комбинации со встро енной функцией reversed(), которая переворачивает строку – напри мер, "".join(reversed(s)), хотя тот же результат может быть получен более кратким оператором извлечения разреженного среза – напри мер, s[:: – 1] Оператор * обеспечивает возможность дублирования строки: >>> s = "=" * 5 >>> print(s) ===== >>> s *= 10 >>> print(s) ================================================== Как показано в примере, мы можем также использовать комбиниро ванный оператор присваивания с дублированием. 1 Когда оператор проверки на вхождение in применяется к строкам, он возвращает True, если операнд слева является подстрокой операнда справа или равен ему. Когда необходимо точно определить позицию подстроки в строке, можно использовать два метода. Первый метод str.index() возвращает позицию подстроки в строке или возбуждает исключение ValueError, если подстрока не будет найдена. Второй метод str.find() возвращает позицию подстроки в строке или – 1 в случае не удачи. Оба метода принимают искомую подстроку в качестве первого аргумента и могут принимать еще пару необязательных аргументов. Второй аргумент определяет позицию начала поиска, а третий – пози цию окончания поиска. Какой из двух методов использовать – это лишь вопрос вкуса, хотя, ес ли выполняется поиск нескольких вхождений одной и той же подстро ки, программный код, использующий метод str.index(), выглядит бо лее понятным, как показано ниже: def extract_from_tag(tag, line): def extract_from_tag(tag, line): opener = "<" + tag + ">" opener = "<" + tag + ">" closer = "" + tag + ">" closer = "" + tag + ">" try: i = line.find(opener) i = line.index(opener) if i != 1: start = i + len(opener) start = i + len(opener) j = line.index(closer, start) j = line.find(closer, start) return line[start:j] if j != 1: except ValueError: return line[start:j] return None return None 1 Строки также поддерживают оператор форматирования %. Этот оператор считается устаревшим и поддерживается только для облегчения перевода программ с версии Python 2 на версию Python 3. Он не используется ни в одном из тех примеров, которые приводятся в книге. Строки 97 Обе версии функции extract_from_tag() обладают одинаковым поведе нием. Например, вызов extract_from_tag("red", "what a this is") возвращает строку «rose». В версии слева, основанной на об работке исключения, программный код, выполняющий поиск, отде лен от программного кода, выполняющего обработку ошибок, а в вер сии справа программный код обработки строки смешивается с про граммным кодом обработки ошибок. Все методы – str.count(), str.endswith(), str.find(), str.rfind(), str.in dex() , str.rindex() и str.startswith() – принимают до двух необяза тельных аргументов: начальную и конечную позиции. Ниже приво дятся два примера эквивалентностей (предполагается, что s – строка): s.count("m", 6) == s[6:].count("m") s.count("m", 5, 3) == s[5:3].count("m") Как видите, строковые методы, принимающие начальную и конечную позиции, действуют со срезом строки, определяемым этими позициями. Теперь взгляните на еще одну пару эквивалентных фрагментов, на этот раз поясняющих действие метода str.partition(): i = s.rfind("/") if i == 1: result = s, "", "" else: result = s.rpartition("/") result = s[:i], s[i], s[i + 1:] Фрагменты программного кода слева и справа не совсем эквивалент ны, потому что фрагмент справа создает новую переменную i. Обрати те внимание, что имеется возможность выполнять присваивание кор тежей без лишних формальностей и что в обоих случаях выполняется поиск самого последнего (крайнего справа) вхождения символа /. Если предполагать, что s – это строка "/usr/local/bin/firefox", то оба фраг мента вернут один и тот же результат: ('/usr/local/bin', '/', 'firefox'). Метод str.endswith() (и str.startswith()) может использоваться с един ственным строковым аргументом, например s.startswith("From:"), или с кортежем строк. Ниже приводится инструкция, в которой использу ются методы str.endswith() и str.lower() для вывода имени файла, ес ли он является файлом изображения в формате JPEG: if filename.lower().endswith((".jpg", ".jpeg")): print(filename, "is a JPEG image") Методы семейства is*, такие как isalpha() и isspace(), возвращают True , если строка, в контексте которой они вызываются, имеет по меньшей мере один символ, и все символы в строке соответствуют оп ределенному критерию. Например: >>> "917.5".isdigit(), "".isdigit(), "2".isdigit(), "203".isdigit() (False, False, False, True) 98 Глава 2. Типы данных Методы семейства is* работают с символами Юникода, поэтому вызов str.isdigit() для строк "\N{circled digit two}03" и " ➁ 03" в обоих случа ях вернет True. По этой причине, когда метод isdigit() возвращает True , нельзя утверждать, что строка может быть преобразована в целое число. Когда мы получаем строки из внешних источников (из других про грамм, из файлов, через сетевые соединения или в результате взаимо действия с пользователем), они могут содержать в начале или в конце нежелательные пробельные символы. Удалить пробельные символы, находящиеся в начале строки, можно с помощью метода str.lstrip(), в конце строки – с помощью метода str.rstrip(), а с обоих концов – с помощью метода str.strip(). Мы можем также передавать методам семейства *strip строки, в этом случае они удалят каждое вхождение каждого символа с соответствующего конца (или с обоих концов) стро ки. Например: >>> s = "\t no parking " >>> s.lstrip(), s.rstrip(), s.strip() ('no parking ', '\t no parking', 'no parking') >>> "<[unbracketed]>".strip("[](){}<>") 'unbracketed' Мы можем также замещать подстроки в строках, ис пользуя метод str.replace(). Этот метод принимает два строковых аргумента и возвращает копию строки, в кон тексте которой был вызван метод, где каждое вхождение строки в первом аргументе замещено строкой во втором аргументе. Если второй аргумент представляет собой пустую строку, это приведет к удалению всех вхождений строки в первом аргументе. Мы увидим примеры ис пользования str.replace() и некоторых других строко вых методов в примере csv2html.py в разделе «Примеры» в конце этой главы. Часто бывает необходимо разбить строку на список строк. Например, у нас может иметься текстовый файл с данными, в котором одной стро ке соответствует одна запись, а поля внутри записи отделяются друг от друга звездочками. Реализовать такое разбиение можно с помощью метода str.split(), передав ему строку, по которой выполняется раз биение, в виде первого аргумента и максимальное число разбиений в виде второго, необязательного аргумента. Если второй аргумент не указан, выполняется столько разбиений, сколько потребуется. Ниже приводится пример использования метода: >>> record = "Leo Tolstoy*1828828*19101120" >>> fields = record.split("*") >>> fields ['Leo Tolstoy', '1828828', '19101120'] Пример csv2html. py , стр. 119 Строки 99 Теперь мы можем с помощью метода str.split() выделить год рожде ния и год смерти и определить, сколько лет прожил Лев Толстой (плюсминус один год): >>> born = fields[1].split("") >>> born ['1828', '8', '28'] >>> died = fields[2].split("") >>> print("lived about", int(died[0]) int(born[0]), "years") lived about 82 years Нам потребовалось использовать преобразование int(), чтобы преобра зовать годы из строк в целые числа, но в остальном в этом фрагменте нет ничего сложного. Мы могли бы получить годы непосредственно из списка fields – например, year_born = int(fields[1].split(" – ")[0]) В табл. 2.7 остались неописанными два метода – str.maketrans() и str.translate(). Метод str.maketrans() используется для создания таб лицы преобразований, которая отображает одни символы в другие. Этот метод принимает один, два или три аргумента, но мы рассмотрим только простейший случай использования (с двумя аргументами), ко гда первый аргумент представляет строку, содержащую символы для преобразования, а второй – строку с символами, в которые нужно пре образовать. Оба аргумента должны иметь одинаковую длину. Метод str.translate() принимает таблицу преобразований и возвращает ко пию строки с символами, преобразованными в соответствии с табли цей преобразований. Ниже приводится пример преобразования бен гальских цифр в английские: table = "".maketrans("\N{bengali digit zero}" "\N{bengali digit one}\N{bengali digit two}" "\N{bengali digit three}\N{bengali digit four}" "\N{bengali digit five}\N{bengali digit six}" "\N{bengali digit seven}\N{bengali digit eight}" "\N{bengali digit nine}", "0123456789") print("20749".translate(table)) # выведет: 20749 print("\N{bengali digit two}07\N{bengali digit four}" "\N{bengali digit nine}".translate(table)) # выведет: 20749 Обратите внимание на то, как в этом примере использовался характер ный для Python прием конкатенации строк в вызове метода str.maket rans() и во втором вызове функции print(), что позволило нам располо жить строки в нескольких строках программного кода, не используя экранирование символов перевода строки и явную операцию конкате нации. Метод str.maketrans() был вызван в контексте пустой строки, потому что совершенно неважно, в контексте какой строки он вызывается – он просто обрабатывает свои аргументы и возвращает таблицу преоб 100 Глава 2. Типы данных разований. 1 Методы str.maketrans() и str.translate() могут также ис пользоваться для удаления символов, если в третьем аргументе методу str.maketrans() передать строку с нежелательными символами. Для бо лее сложных случаев преобразования можно было бы создать отдель ные кодеки; за более подробной информацией о кодеках обращайтесь к описанию модуля codec. В языке Python имеется еще ряд библиотечных модулей, обеспечи вающих дополнительные функциональные возможности при работе со строками. Мы уже упоминали модуль unicodedata и в следующем под разделе покажем, как им пользоваться. Из других модулей, на кото рые следует обратить внимание, можно назвать difflib, который ис пользуется для поиска различий между двумя файлами или строками, класс io.StringIO в модуле io, который позволяет обращаться к стро кам как к файлам, и модуль textwrap, который предоставляет средства обертывания и заполнения строк. Существует также модуль string, в котором имеется несколько полезных констант, таких как ascii_let ters и ascii_lowercase. Примеры использования некоторых из этих мо дулей будут приводиться в главе 5. Кроме того, язык Python обеспечи вает превосходную поддержку регулярных выражений с помощью мо дуля re – этой теме целиком посвящена глава 12. Форматирование строк с помощью метода str.format() Метод str.format() представляет собой очень мощное и гибкое средство создания строк. Использование метода str.format() в простых случаях не вызывает сложностей, но для более сложного форматирования нам необходимо изучить синтаксис форматирования. Метод str.format() возвращает новую строку, замещая поля в контек стной строке соответствующими аргументами. Например: >>> "The novel '{0}' was published in {1}".format("Hard Times", 1854) "The novel 'Hard Times' was published in 1854" Каждое замещаемое поле идентифицируется именем поля в фигурных скобках. Если в качестве имени поля используется целое число, оно определяет порядковый номер аргумента, переданного методу str.for mat() . Поэтому в данном случае поле с именем 0 было замещено пер вым аргументом, а поле с именем 1 – вторым аргументом. Если бы нам потребовалось включить фигурные скобки в строку фор мата, мы могли бы сделать это, дублируя их, как показано ниже: >>> "{{{0}}} {1} ;}}".format("I'm in braces", "I'm not") "{I'm in braces} I'm not ;}" 1 Примечание для программистов, использующих объектноориентирован ный стиль: str.maketrans() – это метод класса. Строки 101 Если попытаться объединить строку и число, интерпретатор Python совершенно справедливо возбудит исключение TypeError. Но это легко можно сделать с помощью метода str.format(): >>> "{0}{1}".format("The amount due is $", 200) 'The amount due is $200' С помощью str.format() мы также легко можем объединять строки (хотя для этой цели лучше подходит метод str.join()): >>> x = "three" >>> s ="{0} {1} {2}" >>> s = s.format("The", x, "tops") >>> s 'The three tops' Здесь мы использовали несколько строковых переменных, тем не ме нее в большинстве примеров с применением метода str.format() в этом разделе мы будем использовать строковые литералы – исключительно ради удобства; но вы должны помнить, что в любых примерах, где ис пользуются строковые литералы, точно также можно было бы исполь зовать и строковые переменные. Замещаемые поля могут определять одним из следующих способов: {field_name} {field_name!conversion} {field_name:format_specification} {field_name!conversion:format_specification} Следует заметить, что замещаемые поля могут содержать другие за мещаемые поля. Вложенные замещаемые поля не могут иметь какое либо форматирование – их назначение состоит в том, чтобы позволить динамически определять параметры форматирования. Примеры ис пользования вложенных полей будут представлены при подробном изучении спецификаторов формата. А теперь приступим к изучению каждой части замещаемого поля, начав с его имени. Имена полей Имя поля может быть либо целым числом, соответствующим одному из аргументов метода str.format(), либо именем одного из именован ных аргументов метода. Именованные аргументы мы будем рассмат ривать в главе 4, но в них нет ничего сложного, поэтому для полноты картины ниже приводится пара примеров: >>> "{who} turned {age} this year".format(who="She", age=88) 'She turned 88 this year' >>> "The {who} was {0} last week".format(12, who="boy") 'The boy was 12 last week' 102 Глава 2. Типы данных В первом примере используются два именованных аргумента, who и age, а во втором – один позиционный аргумент (единственный тип аргу ментов, который мы использовали до сих пор) и один именованный ар гумент. Обратите внимание, что в списке аргументов именованные ар гументы всегда следуют после позиционных, и, конечно же, мы можем использовать в строке формата любые аргументы и в любом порядке. Имена полей могут ссылаться на коллекции, такие как списки. В по добных случаях для идентификации требуемого элемента можно ис пользовать индексы (но не срезы!): >>> stock = ["paper", "envelopes", "notepads", "pens", "paper clips"] >>> "We have {0[1]} and {0[2]} in stock".format(stock) 'We have envelopes and notepads in stock' Поле с именем 0 ссылается на позиционный аргумент, поэтому полю {0[1]} соответствует второй элемент в списке stock, а полю {0[2]} – тре тий элемент в списке stock. Позднее мы познакомимся со словарями в языке Python. Они хранят данные в виде пар «ключзначение», а по скольку они также могут использоваться в качестве ар гументов метода str.format(), приведем короткий при мер. Не волнуйтесь, если чтото покажется вам непонят ным, – вы все поймете, как только прочтете главу 3. >>> d = dict(animal="elephant", weight=12000) >>> "The {0[animal]} weighs {0[weight]}kg".format(d) 'The elephant weighs 12000kg' При обращении к элементам словаря используется ключ, точно так же как используется целочисленный индекс при обращении к элементам списков и кортежей. Мы можем также обращаться к атрибутам объектов по их именам. Предположим, что мы импортировали модули math и sys, тогда можно будет выполнить такое форматирование: >>> "math.pi=={0.pi} sys.maxunicode=={1.maxunicode}".format(math, sys) 'math.pi==3.14159265359 sys.maxunicode==65535' Таким образом, синтаксис имен полей позволяет обращаться как к по зиционным, так и к именованным аргументам, которые передаются методу str.format(). Если в качестве аргументов передаются коллек ции, такие как списки или словари, или объекты, имеющие атрибуты, то имеется возможность обращаться к любой части коллекции, ис пользуя нотацию [] или ., как это показано на рис. 2.5. |