Для того, чтобы начать, здесь приведена краткая инструкция для опытных программистов (которыми вы должны быть, если читаете эту книгу). Вы можете обратиться к полной документации на www.Python.org (особенно невероятно полезна HTML страница "A Python Quick Reference"), а так же к ряду книг, таких как Learning Python Марка Лутца (Mark Lutz) и Дэвида Ашера (David Ascher) (O'Reilly, 1999).
Python часто называют скриптовым языком, но назначение скриптовых языков ограничено, особенно в рамках проблемы, которые они решают. Python, с одной стороны, является языком программирования, который поддерживает скрипты. Он является изумительным языком для скриптов, и вы можете обнаружить, что вы заменяете все свои bat-файлы, скрипты шелла и простенькие программы на Python-скрипты. Но на самом деле это намного больше, чем язык скриптов.
Python предназначен для того, чтобы быть очень чистым для написания и особенно для чтения. Вы можете найти, что он очень прост для чтения вашего собственного кода через долгое время после того, как вы его написали, а так же для чтения кода, написанного другими людьми. Это достигнуто частично через чистый, по сути синтаксический, но главный фактор в читаемости кода - это отступ - контекст в Python определяется отступом. Например:
##interpreter:if.py
response = "yes"
if response == "yes":
print "affirmative"
val = 1
print "continuing..."
##~
'#' обозначает комментарий, который идет до конца строки, аналогично сочетанию '//' в C++ и Java.
Прежде всего заметьте, что основной синтаксис Python схож с C-шным, что видно из оператора if. Но в C if требует использование круглых скобок вокруг выражения, а в Python они не обязательны (но их использование не будет ошибкой).
Проверочное условие завершается двоеточием, которое указывает, что далее следует группа выражений с отступом, которая является "then" частью выражения if. В данном случает это выражение "print", которое посылает результат в стандартный вывод, и следующее присвоение переменной с именем val. Последующие выражения не имеют отступа, так что это больше не часть выражения if. Отступ может формироваться на любом уровне, точно так же как и фигурные скобки в C++ или Java, но в отличие от этих языков, нет правил (и нет аргументов) относительно того, где располагать фигурные скобки - компилятор заставляет, чтобы любой код был отформатирован аналогичным образом, что является одной из главных причин, по которой код Python хорошо читается.
Обычно Python имеет только одно выражение в строке (вы можете поместить больше, разделив их точкой с запятой), таким образом, завершающая точка с запятой не обязательны. Даже из короткого, приведенного выше, примера вы можете видеть, что язык разработан настолько простым, насколько это возможно, и к тому же еще очень легко читаемый.
Встроенные контейнеры
В таких языках, как C++ и Java контейнеры являются дополнительными библиотеками, а не интегрированными в язык. В Python неотъемлемой частью контейнеров для программирования является то, что они встроены в ядро языка: и списки, и ассоциированные массивы (а именно: карты, словари, хэш-таблицы) являются фундаментальными типами данных. Это прибавляет элегантности языку.
Кроме того, выражение for автоматически проходит по списку, а не просто перебором непрерывной последовательности чисел. Это приобретет больший смысл, когда вы подумаете об этом, так как вы почти всегда используете цикл for для прохода по массиву или по контейнеру. Python автоматически формализовал это, сделав for, использующим итератор, который работает с последовательностью. Вот пример:
## interpreter:list.py
list = [ 1, 3, 5, 7, 9, 11 ]
print list
list.append(13)
for x in list:
print x
##~
Первая строка создает список. Вы можете напечатать список и он будет выглядеть точно так, как вы в него помещали (для сравнения, вспомните, что я создавал специальный класс Arrays2 в Thinking in Java, 2nd Edition, чтобы распечатывать массивы в Java). Список похож на Java контейнер - вы можете добавить новый элемент в него (в данном случае используется append( )) и список автоматически увеличит свой размер. В выражении for создается итератор x, который принимает каждое значение из списка.
Вы можете создать список чисел в помощью функции range( ), так что если вам нужно имитировать C-шный for, вы можете это сделать.
Заметьте, что в языке нет деклараций любого типа - просто появляется имя объекта, а Python подразумевает его тип по способу его использования. Таким образом, Python разработан так, что вам нужно просто жать кнопочки, которые должны. Вы обнаружите, после того, как поработаете с Python короткое время, что вы используете огромное число циклов, разделенных точкой с запятой, фигурными скобками и всеми сортами других дополнительных ненужных символов, которые требуются вашим языком программирования, отличным от Python, но на самом деле не описывающих то, для чего ваша программа предназначена.
Функции
Для создания функции в Python вы используете ключевое слово def, за которым следует имя функции и список аргументов, а за двоеточием начинается тело функции. Вот первый пример, включающий функцию:
## interpreter:myFunction.py
def myFunction(response):
val = 0
if response == "yes":
print "affirmative"
val = 1
print "continuing..."
return val
print myFunction("no")
print myFunction("yes")
##~
Обратите внимание, что в сигнатуре функции нет информации о типе - все, что указано, это имя функции и идентификатор аргумента, но нет типа аргумента или типа возвращаемого значения. Python слабо типизированный язык программирования, что означает, что ему необходим минимум из возможно требуемых типов. Например, вы можете передать и вернуть различные типы для одной и той же функции:
## interpreter:differentReturns.py
def differentReturns(arg):
if arg == 1:
return "one"
if arg == "one":
return 1
print differentReturns(1)
print differentReturns("one")
##~
Единственное ограничение состоит в том, что объект, который передается в функцию, был таким, чтобы функция могла работать с этим объектом, но с другой стороны, это не обязательно. Вот одна и та же функция применяет оператор '+' для целых чисел и для строк:
## interpreter:sum.py
def sum(arg1, arg2):
return arg1 + arg2
print sum(42, 47)
print sum('spam', "eggs")
##~
Когда оператор '+' используется со строками, это означает конкатенацию (да, Python поддерживает перегрузку операторов, и это прекрасная работа).
Строки
Приведенный выше пример также демонстрирует обработку строк в Python, которая является лучшей, по сравнению с любым языком, что я видел. Вы можете использовать одинарные или двойные кавычки для представления строк, что очень хорошо, потому, что если вы используете двойные кавычки, вы можете внутри использовать одинарные кавычки, и наоборот:
## interpreter:strings.py
print "That isn't a horse"
print 'You are not a "Viking"'
print """You're just pounding two
coconut halves together."""
print '''"Oh no!" He exclaimed.
"It's the blemange!"'''
print r'c:pythonlibutils'
##~
Заметим, что Python был назван не в честь змеи, а скорее комедийной труппы Монти Пайтона (Monty Python), так что примеры фактически обязаны включать ссылки Python-esque.
Любой синтаксис с тройными кавычками включает новую строку. Это обычно полезно для таких задач, как генерация web страниц (Python особенно удобен в качестве CGI языка), так как вы можете просто включить тройные кавычки без каких-либо дополнений.
Литер 'r' справа перед строкой означает 'raw', это означает, что обратные слешы берутся как литеры и вам не нужно дополнительно печатать обратные слеши.
Подстановка в стоках исключительно легка, так как Python использует C-шный синтаксис подстановки printf( ), но только для всех строк. Вы просто следом за литерой '%' пишите значение для подстановки:
Substitution in strings is exceptionally easy, since Python uses C’s printf( ) substitution syntax, but for any string at all. You simply follow the string with a ‘%’ and the values to substitute:
## interpreter:stringFormatting.py
val = 47
print "The number is %d" % val
val2 = 63.4
s = "val: %d, val2: %f" % (val, val2)
print s
##~
Как вы видите, во втором случае, если вы имеете более одного аргументы, вы окружаете их круглыми скобками (здесь формеруется запись, которая является списком и не может быть изменена).
Поддерживается любое форматирование из printf( ), включая управление числом десятичных знаков и выравниванием. Python также поддерживает очень изощренные регулярные выражения.
Классы
Как и все остальное в Python, определение классов использует минимум дополнительного синтаксиса. Вы используете ключевое слово class, а внутри тела вы используете def для определения методов. Вот пример класса:
## interpreter:SimpleClass.py
class Simple:
def __init__(self, str):
print "Inside the Simple constructor"
self.s = str
# Two methods:
def show(self):
print self.s
def showMsg(self, msg):
print msg + ':',
self.show() #
if __name__ == "__main__":
# :
x = Simple("constructor argument")
x.show()
x.showMsg("A message")
##~
Оба метода имеют 'self' в качестве первого аргумента. C++ и Java прячут первый аргумент в методах класса, который является указателем на текущий объект, вызывающий метод, и может быть доступен при использовании ключевого слова this. Методы Python тоже используют ссылку на текущий объект, но когда вы определяете метод, вы должны явно указать ссылку в качестве первого аргумента. Традиционно эта ссылка называется self, но вы можете использовать любой идентификатор, который хотите (однако, если вы не используете self, вы, вероятно, запутаете большое число людей). Если вам нужна ссылка на поля объекта или на другой метод объекта, вы можете использовать self в выражении. Однако, когда вы вызываете метод для объекта, как в x.show( ), вам не обязательно указывать ссылку на объект - это делается за вас.
В тексте первый метод - специальный, как и любой идентификатор, который начинается с двойного символа подчеркивания. В этом случае он определяет конструктор, который вызывается автоматически при создании объекта, точно как в C++ и Java. Однако в нижней части примера вы можете видеть, что создание объекта выглядит как вызов функции с использованием имени класса. Синтаксис Python позволит вам понять, что на самом деле нет необходимости в ключевом слове new в C++ и Java.
Весь код нижней части является множеством выражения if, которое проверяет, если что-то, называемое __name__ равно __main__. Опять таки, двойное подчеркивание означает специальное имя. Объяснения для if состоит в том, что любой файл может быть использован как модуль библиотеки внутри другой программы (модули описаны коротко). В этом случает вам просто нужно определение класса, но вам не нужен код в нижней части файла, для выполнения. Это особое выражение if возвращает истину, когда вы запускаете этот файл напрямую. Это будет так, если вы напишите в командной строке:
Python SimpleClass.py
Однако если этот файл импортируется как модуль в другую программу, код __main__ не выполняется.
Сначала немного удивляет то, что вы определяете поля внутри методов, а не снаружи методов, как в C++ или Java (если вы создадите поля, используя стиль C++/Java, они неявно станут статическими полями). Для создания поля объекта вы просто объявляете его - используя self - внутри одного из методов (обычно в конструкторе, но не всегда), а место создается при вызове метода. Это выглядит немного странным для перешедших с C++ или Java, когда вы должны сначала решать, сколько места ваш объект будет занимать, не это привносит черезвычайную гибкость в программу.
Наследование
Поскольку Python слабо типизирован, то реально не приходится заботиться об интерфейсах - нужно только заботится о применимости операторов к объекту (фактически, ключевое слово Java interface исчезает в Python). Это означает, что наследование в Python отличается от наследования в C++ или Java, где вы часто наследуете просто для того, чтобы получить общий интерфейс. В Python единственная причина наследования является в наследовании реализации - для повторного использования кода базового класса.
Если вы наследуете от класса, вы должны сказать Pytho'у, чтобы он выделил этот класс в ваш новый файл. Python контролирует пространство имен так же агрессивно, как и Java, причем схожим образом (не смотря на склонность Python к упрощению). При каждом создании файла вы неявно создаете модуль (который аналогичен пакету в Java) с тем же именем, что и этот файл. Таким образом, в Python нет необходимости в ключевом слове package. Когда вы хотите использовать модуль, вы просто пишете import и указываете имя модуля. Python ищет PYTHONPATH точно так же, как Java ищет CLASSPATH (но по некоторым причинам Python не имеет тех же видов неувязок, которые делает Java) и читает файл. Для ссылки на любую функцию или класс внутри модуля вы даете имя модуля, а через точку имя функции или имя класса. Если вы не хотите проблем с именем квалификатора, вы можете сказать
from module import name(s)
Где "name(s)" может быть списком имен, разделенных запятыми.
Вы наследуете класс (или классы - Python поддерживает множественное наследование) перечисляя имя (имена) класса внутри круглых скобок после имени наследуемого класса. Обратите внимание, что класс Simple, который расположен в файле (и поэтому в модуле) с именем SimpleClass перенесен в новое пространство имен с помощью выражения import:
## interpreter:Simple2.py
from SimpleClass import Simple
class Simple2(Simple):
def __init__(self, str):
print "Inside Simple2 constructor"
# Вы должны явно вызвать конструктор
# базового класса:
Simple.__init__(self, str)
def display(self):
self.showMsg("Called from display()")
# Перегрузка метода базового класса
def show(self):
print "Overridden show() method"
# Вызов метода базового класса изнутри
# перегруженного метода:
Simple.show(self)
class Different:
def show(self):
print "Not derived from Simple"
if __name__ == "__main__":
x = Simple2("Simple2 constructor argument")
x.display()
x.show()
x.showMsg("Inside main")
def f(obj): obj.show() # One-line определение
f(x)
f(Different())
##~
Simple2 наследуется от Simple и в конструкторе вызывается конструктор базового класса. В методе display( ) метод showMsg( ) может быть вызван, как метод self, но когда вызывается версия метода базового класса для перегружаемого вами метода, вы должны полностью квалифицировать имя и передать self в качестве первого аргумента, как показано в вызове конструктора базового класса. Это так же можно увидеть в перегруженной версии метода show( ).
В __main__ вы увидите (когда запустите программу), что конструктор базового класса был вызван. Вы также можете видеть, что метод showMsg( ) доступен в наследуемом классе, чего и следовало ожидать при наследовании.
Класс Different также имеет метод с именем show( ) , но этот класс не наследуется от Simple. Метод f( ), определенный в __main__, демонстрирует слабое типизирование: единственное о чем здесь проявлена забота, это чтобы метод show( ) был применим к obj, а на тип не накладывается каких-либо требований. Вы можете видеть, что f( ) может быть применен как к объекту класса, наследуемому от Simple, так и не наследуемому он него, без какой-либо дискриминации. Если вы программист на C++, вы должны заметить, что здесь реализована особенность шаблонов C++: для предоставления слабой типизации в строго типизированном языке. Таким образом, в Python вы автоматически получаете эквивалент шаблонов - без необходимости изучать этот особенно трудный синтаксис и семантику.
← | Мотивация интерпретатора (Interpreter motivation | Создание языка | → |