Математический анализ. 3е издание
Скачать 4.86 Mb.
|
301 >>> L [1, 2, 3, 4, 5, 6, 7, 8] В обоих случаях операция конкатенации несет в себе меньше побочных эффектов при работе с разделяемыми ссылками на объекты, но вообще она выполняется медленнее, чем эквивалентные операции, воздейст вующие на объект непосредственно. Операция конкатенации должна создать новый объект, копию в списке слева, и затем копию в списке справа. В противовес ей метод, воздействующий на объект непосредст венно, просто добавляет новый элемент в конец блока памяти. При использовании дополняющего присваивания для расширения списка мы можем не думать об этих деталях – интерпретатор Python автоматически вызовет более быстрый метод extend вместо использова ния более медленной операции конкатенации, которую предполагает оператор +: >>> L += [9, 10] # Выполняется как L.extend([9, 10]) >>> L [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Дополняющее присваивание и разделяемые ссылки Такой порядок вещей чаще всего именно то, что нам требуется, но не обходимо учитывать – он предполагает, что применительно к спискам операция += выполняет изменения непосредственно в объекте, а это да леко не то же самое, что операция конкатенации +, в результате кото рой всегда создается новый объект. Как всегда в случае использования разделяемых ссылок, различия в поведении этих операций могут иметь значение, если имеются другие ссылки на изменяемый объект: >>> L = [1, 2] >>> M = L # L и M ссылаются на один и тот же объект >>> L = L + [3, 4] # Операция конкатенации создает новый объект >>> L, M # Изменяется L, но не M ([1, 2, 3, 4], [1, 2]) >>> L = [1, 2] >>> M = L >>> L += [3, 4] # Операция += предполагает вызов метода extend >>> L, M # Значение M тоже изменилось! ([1, 2, 3, 4], [1, 2, 3, 4]) Все это имеет значение только для изменяемых объектов, таких как списки и словари, и к тому же это не совсем ясный случай (по крайней мере, пока его влияние не скажется на вашем программном коде!). Ес ли вам требуется избежать создания системы разделяемых ссылок, создавайте копии изменяемых объектов. Правила именования переменных Теперь, когда мы исследовали инструкции присваивания, настало вре мя более формально подойти к вопросу выбора имен переменных. В язы 302 Глава 11. Присваивание, выражения и print ке Python имена появляются в момент, когда им присваиваются некото рые значения, однако существует несколько правил, которым желатель но следовать при выборе имен для всего сущего в ваших программах: Синтаксис: (символ подчеркивания или алфавитный символ) + (любое число символов, цифр или символов подчеркивания) Имена переменных должны начинаться с символа подчеркивания или с алфавитного символа, за которым может следовать произ вольное число алфавитных символов, цифр или символов подчер кивания. Допустимыми именами являются: _spam, spam и Spam_1, а 1_Spam, spam$ и @#! – недопустимыми. Регистр символов в именах имеет значение: имена SPAM и spam считаются различными именами В языке Python регистр символов всегда принимается во внимание, как в именах, которые вы создаете, так и в зарезервированных сло вах. Например, имена X и x – это две разные переменные. Для обес печения переносимости регистр символов учитывается и в именах импортируемых модулей, даже на платформах, где файловые сис темы не учитывают регистр символов. Запрещено использовать зарезервированные слова Имена определяемых вами переменных не могут совпадать с заре зервированными словами, имеющими в языке Python специальное назначение. Например, если попытаться использовать переменную с именем class, интерпретатор выведет сообщение о синтаксиче ской ошибке, однако имена klass и Class являются вполне допусти мыми. В табл. 11.3 перечислены слова, которые в настоящее время зарезервированы языком Python (и, следовательно, запрещены для использования в качестве имен переменных). Таблица 11.3. Зарезервированные слова языка Python В версии Python 2.2 слово yield было необязательным расширени ем, но, начиная с версии 2.3, оно стало стандартным зарезервиро ванным словом. Оно используется совместно с генераторами and elif if pass as (в 2.6 и более поздних) else import print assert except in raise break exec is return class finally lambda try continue for nonlocal (в 3.0) while def from not with (в 2.6 и более поздних) del global or yield Инструкции присваивания 303 функций – новой особенностью, которая будет обсуждаться в гла ве 17. Это один из небольшого числа элементов языка, в котором была нарушена обратная совместимость с прежними версиями. Однако такое преобразование слова yield было выполнено не вдруг – в версии 2.2 при его использовании генерировалось пре дупреждение, и оно было недопустимым до версии 2.3. Похожим образом в Python 2.6 появились новые зарезервирован ные слова with и as для использования в менеджере контекстов (новая форма обработки исключений). В версии 2.5 эти слова не считаются зарезервированными, пока менеджер контекстов не будет включен вручную (подробности приводятся в главе 27). При использовании в версии 2.5 слова with и as вызывают появление предупреждений о грядущих изменениях – исключение состав ляет версия IDLE в Python 2.5, где эта особенность включается ав томатически (т. е. использование этих слов в качестве имен пере менных в версии 2.5 будет вызывать ошибку, но только в интер фейсе IDLE). Зарезервированные слова языка Python всегда записываются симво лами нижнего регистра и они действительно зарезервированы – в от личие от имен в области видимости по умолчанию, о которой будет рассказываться в следующей части книги, вы не можете переопреде лять зарезервированные слова посредством операции присваивания (например, and = 1 приведет к появлению ошибки). 1 Кроме того, поскольку имена модулей в инструкции import становятся переменными в сценарии, это накладывает ограничения на имена фай лов с модулями. Вы можете создать файлы с именами and.py и my+ code.py , но вы не сможете импортировать их, потому что их имена без расширения «.py» в программном коде будут преобразованы в имена пе ременных и поэтому должны следовать только что обозначенным пра вилам (зарезервированные слова запрещены, а символы дефиса являют ся недопустимыми, хотя можно использовать символы подчеркивания). Соглашения по именованию Помимо указанных правил существует еще целый ряд соглашений – правил, которые не являются обязательными, но которым обычно сле дуют на практике. Например, имена с двумя символами подчеркива ния в начале и в конце (например, __name__) обычно имеют особый смысл для интерпретатора, поэтому вам следует избегать их использо вания для именования своих переменных. Ниже приводится список соглашений, которым было бы желательно следовать: • Имена, начинающиеся с одного символа подчеркивания (_X), не им портируются инструкцией from module import * (см. главу 19). 1 Тем не менее, в Jython, реализации Python на языке Java, имена пользова тельских переменных иногда могут совпадать с зарезервированными сло вами языка Python. 304 Глава 11. Присваивание, выражения и print • Имена, имеющие два символа подчеркивания в начале и в конце (__X__), являются системными именами, которые имеют особый смысл для интерпретатора. • Имена, начинающиеся с двух символов подчеркивания и не окан чивающиеся двумя символами подчеркивания (__X), являются ло кальными (автоматически подменяются другими именами) для объемлющего класса (как описывается в главе 26). • Имя, состоящее из единственного символа подчеркивания (_), хра нит результат последнего выражения при работе в интерактивной оболочке. В дополнение к этим соглашениям существует еще ряд других согла шений, которым обычно стремятся следовать программисты. Напри мер, далее в книге мы увидим, что имена классов обычно начинаются с заглавного символа, а имена модулей – с прописного, и что имя self, хотя и не является зарезервированным, играет особую роль в классах. В четвертой части книги мы познакомимся с еще одной крупной кате горией имен, которые называются встроенными, т. е. предопределен ными, но не зарезервированными (вследствие чего они допускают пе реопределение: инструкция open = 42 является вполне допустимой, но иногда вы можете пожалеть, что это так!). Имена не имеют типа, тип – это характеристика объектов По большей части это лишь краткий обзор, но вы должны помнить, что крайне важно сохранить четкое понимание различий между именами и объектами в языке Python. Как говорилось в главе 6 «Интерлюдия о динамической типизации», объекты имеют тип (например, целое чис ло, список) и могут быть изменяемыми или нет. С другой стороны, име на (они же переменные) всегда являются всего лишь ссылками на объ екты – они не имеют информации об изменяемости или о типе отдельно от типа объекта, на который они ссылаются в данный момент времени. Это вполне нормально, когда в разные моменты времени одно и то же имя связывается с объектами разных типов: >>> x = 0 # Имя x связывается с целочисленным объектом >>> x = "Hello" # Теперь оно представляет строку >>> x = [1, 2, 3] # А теперь – список В последующих примерах вы увидите, что такая универсальная при рода имен может рассматриваться как существенное преимущество при программировании на языке Python. 1 В четвертой части книги вы 1 Если вам приходилось пользоваться языком C++, возможно, вас заинтере сует, что в отличие от C++ в языке Python отсутствует объявление const. Некоторые объекты могут быть неизменяемыми, но имена всегда допуска ют выполнение операции присваивания. Кроме того, в языке Python име ются средства сокрытия имен в классах и модулях, но они также не явля ются аналогами объявлений в языке C++. Инструкции выражений 305 узнаете, что имена находятся внутри области видимости, которая определяет, где эти имена могут использоваться – место, где выполня ется присваивание, определяет, где это имя будет видимо. Инструкции выражений В языке Python выражения также могут использоваться в качестве ин струкций (т. е. в отдельной строке). Однако, поскольку результат вы числения таких выражений не сохраняется, использовать такую воз можность имеет смысл только в том случае, если выражение выполня ет какието полезные действия в виде побочного эффекта. В качестве инструкций выражения используются обычно в двух ситуациях: Для вызова функций и методов Некоторые функции и методы выполняют огромный объем работы, не возвращая никакого значения. В других языках программирова ния такие функции иногда называют процедурами. Поскольку они не возвращают значений, которые могло бы потребоваться сохра нить, вы можете вызывать эти функции в инструкциях выражений. Для вывода значений в интерактивной оболоске В ходе интерактивного сеанса интерпретатор автоматически выво дит результаты вводимых выражений. С технической точки зрения они также являются инструкциями выражений и играют роль со кращенной версии инструкции print. В табл. 11.4 перечислены некоторые наиболее часто используемые в языке Python формы инструкций выражений. При вызове функций и методов им передаются ноль или более объектов в виде аргументов (в действительности – выражений, результатом вычисления которых являются объекты) в круглых скобках, следующих за именем функ ции или метода. Таблица 11.4. Наиболее часто используемые в языке Python инструкции выражений Последняя строка в таблице представляет специальную форму: язык Python позволяет объединять операции сравнения, чтобы выполнить серию сравнений в таких операциях, как проверка на принадлежность Операция Интерпретация spam(eggs, ham) Вызов функции spam.ham(eggs) Вызов метода spam Вывод значения переменной в интерактивной оболочке интерпретатора spam < ham and ham != eggs Составное выражение spam < ham < eggs Проверка на принадлежность диапазону 306 Глава 11. Присваивание, выражения и print диапазону значений. Например, выражение (A < B < C) проверяет, при надлежит ли B диапазону значений от A до C – оно эквивалентно логи ческому выражению (A < B and B < C), но оно проще воспринимается ви зуально (и его проще вводить). Составные выражения обычно не запи сываются в виде самостоятельных инструкций, но с точки зрения син таксиса являются вполне допустимыми и могут быть даже полезными при работе в интерактивной оболочке, когда вы не уверены в результа те выражения. Несмотря на то, что выражения могут играть роль инструкций в языке Python, сами инструкции не могут использоваться в качестве выраже ний. Например, язык Python не допускает встраивание инструкции присваивания (=) в выражения. Сделано это специально для того, что бы помочь избежать ошибок – вы могли бы случайно изменить пере менную, введя вместо оператора проверки равенства == оператор при сваивания =. В главе 13 будет показано, как отсутствие такой возмож ности может быть компенсировано в языке Python, когда мы будем об суждать цикл while. Инструкции выражений и непосредственное изменение объектов Инструкции выражений являются причиной распространенной ошиб ки при программировании на языке Python. Инструкции выражений часто используются для вызова методов списка, которые непосредст венно изменяют сам список: >>> L = [1, 2] >>> L.append(3) # Метод append изменяет сам список >>> L [1, 2, 3] Однако начинающие программисты нередко записывают такие опера ции в виде инструкций присваивания, пытаясь связать имя L со спи ском: >>> L = L.append(4) # Но метод append возвращает значение None, а не L >>> print L # Поэтому мы теряем весь список! None Такая операция дает неверный результат – такие методы списка, как apend , sort и reverse, всегда выполняют непосредственное изменение объекта, но они не возвращают список, который был изменен с их по мощью. В действительности они возвращают объект None. Если результат та кой операции присвоить той же переменной, вы потеряете список (скорее всего, он будет уничтожен в ходе процесса сборки мусора!). Поэтому не делайте этого. Мы еще раз вернемся к этому явлению в раз деле «Распространенные ошибки программирования» в конце этой части книги, потому что подобные ситуации могут складываться в кон Инструкция print 307 тексте выполнения некоторых операторов цикла, с которыми мы по знакомимся в последующих главах. Инструкция print Инструкция print производит вывод на экран – это просто удобный для программистов интерфейс к стандартному потоку вывода. С тех нической точки зрения эта инструкция преобразует объекты в тексто вое представление и посылает результат на устройство стандартного вывода. Поток стандартного вывода в языке Python – это то же самое, что stdout в языке C; обычно он отображается на окно, в котором была за пущена программа на языке Python (если стандартный вывод не был перенаправлен в файл или в канал средствами системной командной оболочки). В главе 9 мы рассматривали некоторые методы для работы с файлами, которые выводят текст. Инструкция print чемто похожа на них, но она имеет более специализированное назначение: инструкция print записы вает объекты в поток stdout (с соблюдением некоторого форматирования по умолчанию), в то время как методы файлов записывают строки в про извольные файлы. Так как поток стандартного вывода в языке Python доступен в виде объекта stdout встроенного модуля sys (т. е., sys.stdout), вполне возможно имитировать поведение инструкции print с помощью методов записи в файл, хотя использование print выглядит проще. Таблица 11.5. Перечень форм инструкции print Мы уже видели инструкцию print в действии. По умолчанию она до бавляет пробел между элементами, отделенными запятыми, и символ конца строки в конце текущей строки вывода: >>> x = 'a' >>> y = 'b' >>> print x, y a b Такое форматирование – всего лишь значение по умолчанию, которое можно использовать или нет. Чтобы подавить вывод символа конца строки (чтобы позднее можно было продолжить вывод текста в текущую Операция Интерпретация print spam, ham Вывод объектов в sys.stdout; добавляет пробел между объектами и символ конца строки print spam, ham, То же самое, только на этот раз символ конца строки не добавляется print >> myfile, spam, ham Текст передается методу myfile.write, а не sys.stdout.write 308 Глава 11. Присваивание, выражения и print строку), инструкцию print следует завершать символом запятой, как показано во второй строке табл. 11.5. Чтобы подавить вывод пробела между элементами, не следует производить вывод таким способом – вместо этого нужно самостоятельно собрать строку с помощью средств конкатенации и форматирования, о которых рассказывалось в главе 7, и вывести эту строку: >>> print x + y ab >>> print '%s...%s' % (x, y) a...b Программа «Hello World» на языке Python Чтобы вывести сообщение «hello world», достаточно просто напечатать строку: >>> print 'hello world' # Вывести строковый объект hello world Поскольку результаты выражений в интерактивной оболочке выво дятся автоматически, вы можете даже не использовать инструкцию print – просто введите выражение, которое требуется вывести, и ре зультат его вычисления немедленно будет выведен: >>> 'hello world' # Интерактивная оболочка выводит автоматически 'hello world' В действительности инструкция print – это всего лишь эргономичная особенность языка Python – она обеспечивает простой интерфейс к объ екту sys.stdout, добавляя незначительный объем форматирования. Фактически, если вам нравится идти более трудным путем, вы можете запрограммировать вывод таким способом: >>> |