Общие характеристики скриптовых языков. Язык Python
Содержание:
1.Введение.
В связи с наблюдаемым в настоящее время стремительным развитием персональной вычислительной техники, происходит постепенное изменение требований, предъявляемых к языкам программирования. Все большую роль начинают играть интерпретируемые языки, поскольку возрастающая мощь персональных компьютеров начинает обеспечивать достаточную скорость выполнения интерпретируемых программ. А единственным существенным преимуществом компилируемых языков программирования является создаваемый ими высокоскоростной код. Когда скорость выполнения программы не является критичной величиной, наиболее правильным выбором будет интерпретируемый язык, как более простой и гибкий инструмент программирования.
В связи с этим, определенный интерес представляет рассмотрение сравнительно нового языка программирования Python (пайтон), который был создан его автором Гвидо ван Россумом (Guido van Rossum) в начале 90-х годов.
2.Общие сведения о Python. Достоинства и недостатки.
Python является интерпретируемым, изначально объектно-ориентированным языком программирования. Он чрезвычайно прост и содержит небольшое число ключевых слов, вместе с тем очень гибок и выразителен. Это язык более высокого уровня, нежели Pascal, C++ и, естественно C, что достигается, в основном, за счет встроенных высокоуровневых структур данных (списки, словари, тьюплы).
2.1Достоинства языка.
Несомненным достоинством является то, что интерпретатор Python реализован практически на всех платформах и операционных системах. Первым таким языком был C, однако его типы на разных машинах могли занимать разное количество памяти и это служило некоторым препятствием при написании действительно переносимой программы. Python же таким недостатком не обладает.
Следующая немаловажная черта - расширяемость языка, этому придается большое значение и, как пишет сам автор, язык был задуман именно как расширяемый. Это означает, что имеется возможность совершенствования языка всеми желающими. Интерпретатор написан на С и исходный код доступен для любых манипуляций. В случае необходимости, можно вставить его в свою программу и использовать как встроенную оболочку. Или же, написав на C свои дополнения к Python и скомпилировав программу, получить «расширенный» интерпретатор с новыми возможностями.
Следующее достоинство - наличие большого числа подключаемых к программе модулей, обеспечивающих различные дополнительные возможности. Такие модули пишутся на С и на самом Python и могут быть разработаны всеми достаточно квалифицированными программистами. В качестве примера можно привести следующие модули:
- Numerical Python - расширенные математические возможности, такие как манипуляции с целыми векторами и матрицами;
- Tkinter - построение приложений с использованием графического пользовательского интерфейса (GUI) на основе широко распространенного на X-Windows Tk-интерфейса;
- OpenGL - использование обширной библиотеки графического моделирования двух- и трехмерных объектов Open Graphics Library фирмы Silicon Graphics Inc. Данный стандарт поддерживается, в том числе, в таких распространенных операционных системах как Microsoft Windows 95 OSR 2, 98 и Windows NT 4.0.
2.2Недостатки языка.
Единственным недостатком, замеченным автором, является сравнительно невысокая скорость выполнения Python-программы, что обусловлено ее интерпретируемостью. Однако на наш взгляд, это с лихвой окупается достоинствами языка при написании программ не очень критичных к скорости выполнения.
3.Обзор особенностей.
- Python, в отличие от многих языков (Pascal, C++, Java, и т.д.), не требует описания переменных. Они создаются в месте их инициализации, т.е. при первом присваивании переменной какого-либо значения. Значит, тип переменной определяется типом присваиваемого значения. В этом отношении Python напоминает Basic.
Тип переменной не является неизменным. Любое присваивание для нее корректно и это приводит лишь к тому, что типом переменной становится тип нового присваиваемого значения.
2. В таких языках как Pascal, C, C++ организация списков представляла некоторые трудности. Для их реализации приходилось хорошо изучать принципы работы с указателями и динамической памятью. И даже имея хорошую квалификацию, программист каждый раз заново реализуя механизмы создания, работы и уничтожения списков, мог легко допустить трудноуловимые ошибки. Ввиду этого были созданы некоторые средства для работы со списками. Например, в Delphi Pascal имеется класс TList, реализующий списки; для С++ разработана библиотека STL (Standard Template Library), содержащая такие структуры как векторы, списки, множества, словари, стеки и очереди. Однако такие средства имеются не во всех языках и их реализациях.
Одной из отличительных черт Python является наличие таких встроенных в сам язык структур как тьюплы (tuple), списки (list) и словари (dictionary), которые иногда называют картами (map). Рассмотрим их подробней.
- Тьюпл. Он чем-то напоминает массив: состоит из элементов и имеет строго определенную длину. Элементами могут быть любые значения - простые константы или объекты. В отличие от массива, элементы тьюпла не обязательно однородны. А тем, что отличает тьюпл от списка (list) является то, что тьюпл не может быть изменен, т.е. мы не можем i-тому элементу тьюпла присвоить что-то новое, и не можем добавлять новые элементы. Таким образом, тьюпл можно назвать списком-константой. Синтаксически тьюпл задается путем перечисления через запятую всех элементов, и все это заключено в круглые скобки:
(1, 2, 5, 8)
(3.14, ‘ string ’, -4)
Все элементы индексируются с нуля. Для получения i-го элемента необходимо указать имя тьюпла затем индекс i в квадратных скобках. Пример:
t = (0,1,2,3,4)
print t[0], t[-1], t[-3]
Результат: 0 4 2
Таким образом, тьюпл можно было назвать вектором-константой, если бы его элементы всегда были однородными.
- Список. Хорошим, частным примером списка может служить строка (string) языка Turbo Pascal. Элементами строки являются одиночные символы, ее длина не фиксирована, имеется возможность удалять элементы или, напротив, вставлять их в любом месте строки. Элементами же списка могут быть произвольные объекты не обязательно одного и того же типа. Чтобы создать список, достаточно перечислить его элементы через запятую, заключив все это в квадратные скобки:
[3, 5.14, ‘s’]
[‘string’, (0,1,8), [1,1]]
В отличие от тьюпла, списки можно модифицировать по своему желанию. Доступ к элементам осуществляется также как и в тьюплах. Пример:
l = [1, ‘s’, (2,8), [0,3,4]]
print l[0], l[1], l[-2], l[-1][0]
Результат: 1 s (2,8) 0
- Словарь. Напоминает тип запись (record) в Pascal или структуры (structure) в С. Однако, вместо схемы «поле записи»-«значение» здесь применяется «ключ»-«значение». Словарь представляет собой набор пар «ключ»-«значение». Здесь «ключ» - константа любого типа (но преимущественно применяются строки), он служит для именования (индексирования) некоторого соответствующего ему значения (которое можно менять). Словарь создается путем перечисления его элементов (пар "ключ"-"значение", разделенных двоеточием), через запятую и заключения всего этого в фигурные скобки. Для получения доступа к некоторому значению необходимо, после имени словаря, записать соответствующий ключ. Пример:
d = {'a': 1, 'b': 3, 5: 3.14, 'name': 'John'}
d['b'] = d[5]
print d['a'], d['b'], d[5], d['name']
Результат: 1 3.14 3.14 John
Для добавления новой пары "ключ"-"значение" достаточно присвоить элементу с новым ключом соответствующее значение:
d['new'] = 'new value'
print d
Результат: {'a':1, 'b':3, 5:3.14, 'name':'John', 'new':'new value'}
3. Python в отличие от Pascal, C, C++ не поддерживает работу с указателями, динамической памятью и адресную арифметику. В этом он похож на Java. Как известно, указатели служат источником трудноуловимых ошибок, и работа с ними относится больше к программированию на низком уровне. Для обеспечения большей надежности и простоты они небыли включены в Python.
4. Одним из особенностей Python является то, как происходит присваивание одной переменной другой, т.е. когда по обе стороны от оператора "=" стоят переменные.
Следуя Тимоти Бадду ([1]), будем называть семантикой указателей случай, когда присваивание приводит лишь к присваиванию ссылки (указателя), т.е. новая переменная становится лишь другим именем, обозначающим тот же участок памяти что и старая переменная. При этом изменение значения, обозначаемого новой переменной, приведет к изменению значения старой, т.к. они, фактически, означают одно и то же.
Когда же присваивание приводит к созданию нового объекта (здесь объект - в смысле участка памяти для хранения значения какого-либо типа) и копированию в него содержимого присваиваемой переменной, этот случай назовем семантикой копирования. Таким образом, если при копировании действует семантика копирования, то переменные по обе стороны от знака "=" будут означать два независимых объекта с одинаковым содержанием. И здесь последующее изменение одной переменной никак не скажется на другой.
Присваивание в Python происходит следующим образом: если присваеваемый объект является экземпляром таких типов как числа или строки, то действует семантика копирования, если же в правой части стоит экземпляр класса, список, словарь или тьюпл, то действует семантика указателей. Пример:
a = 2; b = a; b = 3
print 'семантика копирования: a=', a, 'b=', b
a=[2,5]; b = a; b[0] = 3
print 'семантика указателей: a=', a, 'b=', b
Результат:
семантика копирования: a= 2 b= 3
семантика указателей: a= [3,5] b= [3,5]
Для тех из вас, кто хочет знать, в чем тут дело, я приведу другой взгляд на присваивание в Python. Если в таких языках как Basic, Pascal, C/C++ мы имели дело с переменными-«емкостями», и хранимыми в них константами (числовыми, символьными, строковыми - не суть важно), а операция присваивания означала «занесение» константы в присваиваемую переменную, то в Python мы уже должны работать с переменными-«именами» и именуемыми ими объектами. (Замечаете некоторую аналогию с языком Prolog?) Что же такое объект в Python? Это все то, чему можно дать имя: числа, строки, списки, словари, экземпляры классов (которые в Object Pascal и называются объектами), сами классы (!), функции, модули и т.д. Так вот, при присваивании переменной некоторого объекта, переменная становится его «именем», причем таких «имен» объект может иметь сколько угодно и все они никак не зависят друг от друга.
Теперь, объекты делятся на модифицируемые (мутируемые) и неизменные. Мутируемые - те, которые могут изменить свое «внутреннее содержание», например, списки, словари, экземпляры классов. А неизменные - такие как числа, тьюплы, строки (да, строки тоже; можно переменной присвоить новую строку, полученную из старой, но саму старую строку модифицировать не получится).
Так вот, если мы пишем:
a=[2,5]; b = a; b[0] = 3
Python это интерпретирует так:
- дать объекту «список [2,5]» имя a;
- дать этому объекту еще одно имя - b;
- модифицировать нулевой элемент объекта.
Вот и получилась «псевдо» семантика указателей.
И последнее, что стоит сказать насчет этого: хотя нет возможности изменения структуры тьюпла, но содержащиеся в нем мутируемые компоненты по-прежнему доступны для модификации:
t = (1, 2, [7,5], 'string')
t[0] = 6 # так нельзя
del t[1] # тоже ошибка
t[2][1] = 0 # допустимо,
# теперь третья компонента - список [7,0]
t[3][0] = 'S' # ошибка: строки не мутируемы
5. Весьма оригинальным является то, как в Python группируются операторы. В Pascal для этого служат операторные скобки begin-end, в C, C++, Java - фигурные скобки {}, в Basic применяются закрывающие окончания конструкций языка (NEXT, WEND, END IF, END SUB).
В языке Python все гораздо проще: выделение блока операторов осуществляется путем сдвига выделяемой группы на один или более пробелов или символов табуляции вправо относительно заголовка конструкции, к которой и будет относиться данный блок. Например:
if x > 0:
print ‘ x > 0 ’
x = x - 8
else:
print ‘ x <= 0 ’
x = 0
Тем самым, хороший стиль записи программ, к которому призывают преподаватели языков Pascal, C++, Java и т.д., здесь приобретается с самого начала, поскольку по-другому просто не получится.
4.Описание языка. Управляющие конструкции.
if <условие1>: <оператор1>
[elif <условие2>: <оператор2>]*
[else: <оператор3>]
Оператор «если». Часть в квадратных скобках является необязательной. Следующий за скобками символ «*» означает, что заключенная в скобки часть может быть записана неоднократно одна за другой.
Здесь, при истинности <условия1> будет выполнен <оператор1> и проигнорированы ветки elif и else. В противном случае, если истинно <условие2>, то выполняется <оператор2>, ветка else игнорируется. Иначе выполняется <оператор3>.
while <условие>: <оператор1>
[else: <оператор2>]
Цикл «пока». <Оператор1> будет выполняться все время, пока истинно <условие>. При нормальном завершении цикла, т.е. без применения break, выполнится <оператор2>.
for <переменная> in <список>: <оператор1>
[else: <оператор2>]
Цикл «для». <Переменная> пробегает все элементы <списка> и для каждого текущего значения <переменной> выполняется <оператор1>. При нормальном завершении цикла, т.е. без применения break, выполнится <оператор2>.
break
Осуществляет немедленное завершение циклов while и for.
continue
Вызывает немедленное выполнение следующей итерации циклов while и for.
return [<результат>]
Осуществляет возврат из функции или метода класса, возвращая значение <результат>.
5.Обработка исключительных ситуаций.
try: <оператор1>
[except [<исключение> [,<переменная>] ]: < оператор2>]
[else <оператор3>]
Выполняется <оператор1>, если при этом возникла исключительная ситуация <исключение>, то выполняется <оператор2>. Если <исключение> имеет значение, то оно присваивается <переменной>.
В случае успешного завершения <оператора1> выполняется <оператор3>.
try: <оператор1>
finally: <оператор2>
Выполняется <оператор1>. Если не возникло исключений, то выполняется <оператор2>. Иначе выполняется <оператор2> и немедленно инициируется исключительная ситуация.
raise <исключение> [<значение>]
Инициирует исключительную ситуацию <исключение> с параметром <значение>.
Исключения - это просто строки (string). Пример:
my_ex = ‘bad index’
try:
if bad:
raise my_ex, bad
except my_ex, value:
print ‘ Error ’, value
6.Объявление функций.
def <имя_функции> ([<список_параметров>]):
<тело_функции>
Здесь <тело_функции> - последовательность операторов, выровненных по тексту правее слова «def».
<список_параметров> в самом общем виде выглядит так:
[ [,]* ] [ = [,=]* ] [, *]
Здесь - идентификатор переменной; - некое значение.
Параметры , за которыми следует «=» получают значения по умолчанию.
Если список заканчивается строкой « * », то id присваивается тьюпл (tuple) из всех оставшихся аргументов, переданных функции.
7.Объявление классов.
class <имя_класса> [( <предок1> [,<предок2>]* )]:
<тело_класса>
Здесь <тело_класса> может содержать присваивания переменным (эти переменные становятся атрибутами, т.е. полями класса) и определений функций (являющихся методами класса).
Первым аргументом метода всегда является экземпляр класса, который вызывает данный метод (или к которому применяется метод). По соглашению, этот аргумент называется «self». Специальный метод __init__() вызывается автоматически при создании экземпляра класса.
Пример:
class cMyClass:
def __init__(self, val):
self.value = val
#
def printVal (self):
print ‘ value = ’, self.value
#
# end cMyClass
obj = cMyClass (3.14)
obj.printVal ()
obj.value = « string now »
obj.printVal ()
Результат:
value = 3.14
value = string now
8.Операторы для всех типов последовательностей
(списки, тьюплы, строки).
len (s) - возвращает длину s.
min (s), max (s) - наименьший и наибольший элементы s, соответственно.
x in s - истина (1), если s включает в себя элемент равный x, иначе - ложь (0).
x not in s - ложь если s включает x, иначе истина.
s+t - слияние s и t.
s*n, n*s - n копий s, слитых вместе (например, ‘*’ * 5 - это строка ‘*****’).
s[i] - i-тый элемент s, где i отсчитывается с 0.
s[i:j] - часть элементов s начиная с i до j-1 включительно. Либо i, либо j, либо оба параметра могут быть опущены (i по умолчанию равен 0, j - длине s).
9.Операторы для списков (list).
s[i] = x - i-тый элемент s заменяется на x.
s[i:j] = t - часть элементов s от i до j-1 заменяется на t (t может быть также списком).
del s[i:j] - удаляет часть s (также, как и s[i:j] = []).
s.append (x) - добавляет элемент x к концу s.
s.count (x) - возвращает количество элементов s, равных x.
dex (x) - возвращает наименьший i такой, что s[i]==x.
sert (i,j) - часть s, начиная с i-го элемента, сдвигается вправо, и s[i] присваивается x.
s.remove (x) - то же, что и del s[ dex(x) ] - удаляет первый элемент s, равный x.
s.reverse () - записывает строку в обратном порядке.
s.sort () - сортирует список по возрастанию.
10.Операторы для словарей (dictionary).
len (a) - количество элементов а.
a[k] - элемент с ключом k.
a[k] = x - присвоить элементу с ключом k значение x.
del a[k] - удалить a[k] из словаря.
a.items () - список тьюплов пар (ключ, значение).
a.keys () - список ключей а.
a.values () - список значений а.
a.has_key (k) - возвращает 1, если а имеет ключ k, иначе 0.
11.Файловые объекты.
Создаются встроенной функцией open() (ее описание смотрите ниже). Например: f = open (‘mydan.dat’, ‘r’). Методы:
f.close () - закрыть файл.
f.read ([size]) - читает байт из файла и возвращает в виде строки. Если отсутствует, то читает до конца файла.
f.readline () - читает целиком одну строку из файла.
f.readlines () - читает строки до конца файла и возвращает список прочитанных строк.
f.seek (offset, mode) - устанавливает позицию в файле с которого будет произведено чтение. - смещение относительно:
- начала файла (при mode == 0 - по умолчанию);
- текущей позиции (при mode == 1);
- конца файла (при mode == 2).
f.tell () - возвращает текущую позицию в файле.
f.write (str) - записывает строку в файл.
12.Другие элементы языка и встроенные функции.
= присваивание.
print [ [,]* [,] ] - выводит значения , в стандартный вывод. Ставит пробел между аргументами. Если запятая в конце перечня аргументов отсутствует, то осуществляет переход на новую строку.
abs (x) - возвращает абсолютное значение x.
apply (f, <аргументы>) - вызывает функцию (или метод) f с < аргументами >.
chr (i) - возвращает односимвольную строку с ASCII кодом i.
cmp (x, y) - возвращает отрицательное, ноль, или положительное значение, если, соответственно, x <, ==, или > чем y.
divmod (a, b) - возвращает тьюпл ( a/b, a%b ), где a/b - это a div b (целая часть результата деления), a%b - это a mod b (остаток от деления).
eval (s) - возвращает объект, заданный в s как строка (string). S может содержать любую структуру языка. S так же может быть кодовым объектом, например: x = 1; incr_x = eval («x+1»).
float (x) - возвращает вещественное значение равное числу x.
hex (x) - возвращает строку, содержащую шестнадцатеричное представление числа x.
input (<строка>) - выводит <строку>, считывает и возвращает значение со стандартного ввода.
int (x) - возвращает целое значение числа x.
len (s) - возвращает длину (количество элементов) объекта.
long (x) - возвращает значение типа длинного целого числа x.
max (s), min (s) - возвращают наибольший и наименьший из элементов последовательности s ( т.е. s - строка, список или тьюпл )
oct (x) - возвращает строку, содержащую представление числа x.
open (<имя файла>, <режим> = ‘r’) - возвращает файловый объект, открытый для чтения. <режим> = ‘w’ - открытие для записи.
ord (c) - возвращает ASCII код символа (строки длины 1) c.
pow (x, y) - возвращает значение x в степени y.
range (<начало>, <конец>, <шаг>) - возвращает список целых чисел, больших либо равных <начало> и меньших чем <конец>, сгенерированных с заданным <шагом>.
raw_input ([<текст>]) - выводит <текст> на стандартный вывод и считывает строку (string) со стандартного ввода.
round (x, n=0) - возвращает вещественное x, округленное до n-го разряда после запятой.
str (<объект>) - возвращает строковое представление <объекта>.
type (<объект>) - возвращает тип объекта. Например:
if type(x) == type(‘’): print ‘ это строка ’
xrange (<начало>, <конец>, <шаг>) - аналогичен range, но лишь имитирует список, не создавая его. Используется в цикле for.
13.Cпециальные функции для работы со списками.
filter (<функция>, <список>) - возвращает список из тех элементов <спиcка>, для которых <функция> принимает значение «истина».
map (<функция>, <список>) - применяет <функцию> к каждому элементу <списка> и возвращает список результатов.
reduce (f, <список>, [, <начальное значение> ]) - возвращает значение, полученное «редуцированием» <списка> функцией f. Это значит, что имеется некая внутренняя переменная p, которая инициализируется <начальным значением>, затем, для каждого элемента <списка>, вызывается функция f с двумя параметрами: p и элементом <списка>. Возвращаемый f результат присваивается p. После перебора всего <списка> reduce возвращает p.
С помощью данной функции можно, к примеру, вычислить сумму элементов списка:
def func (red, el):
return red+el
sum = reduce (func, [1,2,3,4,5], 0)
# теперь sum == 15
lambda [<список параметров>]: <выражение> - «анонимная» функция, не имеющая своего имени и записываемая в месте своего вызова. Принимает параметры, заданные в <списке параметров>, и возвращает значение <выражения>. Используется для filter, reduce, map. Например:
>>>print filter (lambda x: x>3, [1,2,3,4,5])
[4, 5]
>>>print map (lambda x: x*2, [1,2,3,4])
[2, 4, 6, 8]
>>>print reduce (lambda r, x: r*x, [1,2,3,4], 1)
24
14.Импортирование модулей.
import <модуль1> [, <модуль2> ]* - подключает внешние модули.
from <модуль> import <имя1> [, <имя2> ]* - импортирует имена (функций, классов, переменных и т.д.) из <модуля>.
from <модуль> import * - импортирует все имена из <модуля>, за исключением начинающихся символом «_».
15.Стандартный модуль math.
Переменные: pi, e.
Функции (аналогичны функциям языка C):
acos(x) |
cosh(x) |
ldexp(x,y) |
sqrt(x) |
asin(x) |
exp(x) |
log(x) |
tan(x) |
atan(x) |
fabs(x) |
sinh(x) |
frexp(x) |
atan2(x,y) |
floor(x) |
pow(x,y) |
modf(x) |
ceil(x) |
fmod(x,y) |
sin(x) |
|
cos(x) |
log10(x) |
tanh(x) |
16.Модуль string.
Функции:
index (s, sub, i=0) - возвращает индекс первого вхождения подстроки sub в строку s, начиная с позиции i.
lower (s) - возвращает строку s в нижнем регистре букв.
splitfields (s, sep) - возвращает список подстрок строк s разделенных символом sep.
joinfields (<слова>, <разделитель>) - сцепляет список или тьюпл <слова>, используя <разделитель>.
strip (s) - возвращает строку, полученную из s путем исключения пробелов.
upper (s) - возвращает строку s в верхнем регистре букв.
17.Заключение.
Благодаря простоте и гибкости языка Python, его можно рекомендовать пользователям (математикам, физикам, экономистам и т.д.) не являющимся программистами, но использующими вычислительную технику и программирование в своей работе.
Программы на Python разрабатываются в среднем в полтора-два (а порой и в два-три) раза быстрее, нежели на компилируемых языках (С, С++, Pascal). Поэтому, язык может представлять не малый интерес и для профессиональных программистов, разрабатывающих приложения, не критичные к скорости выполнения, а также программы, использующие сложные структуры данных. В частности, Python хорошо зарекомендовал себя при разработке программ работы с графами, генерации деревьев.
18. Список Литературы.
- Бадд Т. Объектно-ориентированное программирование.
- СПб.: Питер,2012. - Guido van Rossum. Python Tutorial.
- Chris Hoffman. A Python Quick Reference.
- Guido van Rossum. Python Library Reference.
- Guido van Rossum. Python Reference Manual.
- Гвидо ван Россум. Семинар по программированию на Python.
- Архитектура ANSI-SPARC
- Основы оценки нематериальных активов и объектов интеллектуальной собственности
- Способы доставки телевизионного контента
- Проблемы формирования амортизации ОС и НМА после переоценки
- История развития менеджмента как науки
- Информационный менеджмент
- Классификация преступлений в международном праве
- Процесс регистрации документов
- Корпоративное управление государственной собственностью
- Виды интернет-рекламы (Понятие и цели Интернет-рекламы)
- Административно-правовые нормы: общая характеристика
- Сравнительный анализ систем обнаружения атак или вторжений