Ваша первая программа

 

Приручаем змея

 

Good bye, world!

 

Вообще, писать на питоне программы типа Hello World! на мой взгляд - пустая трата времени. Этот язык обладает настолько мощными средствами… но я, кажется, уже рассказывал. Без особых усилий на нём можно написать программу Good bye, World!, которая отправит запрос в Пентагон, в центр наведения ядерных ракет и программно жмякнет Большую Красную Кнопку. Надо только знать пароль… Вот это – хороший пример для новичка, иллюстрирующий одновременно работу с сетью, файлами, базами данных и дополнительной справочной литературой (см. «Статья 272 УК РФ»).  Что? Не хотите? Ну и не надо. Придумаем что-нибудь попроще.

 

Итак, наша первая программа будет работать с сетью. Собственно, сеть – одно из направлений, где Python наиболее активно применяется, наравне с PHP и Perl.

 

Задача – узнать погоду на космодроме Байконур.

 

К счастью, собирать данные близлежащих метеостанций нам не придётся. За нас всё сделал Яндекс, от нас требуется лишь вежливо попросить у него нужную инфу. Сама информация доступна по адресу http://info.weather.yandex.net/baikonur/1.png  (можете проверить). Это обычная картинка в формате png. Задача программы – получить (скачать) эту картинку, сохранить на диске, и сделать так, чтобы мы её увидели, то есть открыть в соответствующей программе. Начнём!

 

1) Все питон-программы – это обычные текстовые файлы с расширением PY (английскими буквами). Поэтому перво-наперво нужно связать этот тип файлов с интерпретатором python.exe, который обычно располагается в папке на диске Це. У вашей первой программы должен появиться симпатичный маленький значок в виде синего питона и жёлтой питонихи. Сделали?

 

 

Отныне двойной щелчок по такому файлу будет означать запуск программы. Пока нам это без надобности, и мы открываем свою первую программу при помощи уже представленного вам Notepad++.

 

 

Полагаю, на этом этапе проблем не возникло. Если возникло – читать предыдущий пункт «до просветления». Серьёзно. Как можно идти дальше, если вы не в состоянии сделать элементарную вещь? Не надо парить, мол «плохо объяснял». Нормально объяснял. С картинками даже. Дальше будет сложнее, предупреждаю заранее.

 

2) С первым пунктом справились. Перед нами – редактор, в нём – чистый лист. Это очень плохо! Ведь только вчера мы с вами обсуждали нюансы различных кодировок. Первая строка, с которой должна начинаться любая питон-программа – это строка с указанием кодировки!

 

# -*- coding: cp1251 -*-

 

Можно работать в cp-1251 (ANSI), а можно – и в юникоде, как это делают профи. Отличие – в одной строчке и одной галочке в меню «Кодировки». Выбор за вами.

 

Да, чуть не забыл. Всё что идёт после символа решётки (#) считается, как вы уже знаете, комментарием. Большое количество качественных (по существу) комментариев в программе повышает её качество и удобочитаемость.  Не скупитесь объяснять гипотетическому собеседнику смысл каждой написанной вами строчки. Договорились?

 

3) Разобрались с языками кодировками. Будем надеяться – Питон нас поймёт. Теперь… Теперь вспомним что такое модуль. Модуль – это…? Ну? Эх, вы… Модуль представляет собой функционально законченный фрагмент программы, оформленный в виде отдельного файла с исходным кодом, предназначенный для использования в других программах. Модули позволяют разбивать сложные задачи на более мелкие в соответствии с принципом модульности. Обычно модули проектируются таким образом, чтобы предоставлять программистам удобную для многократного использования функциональность (интерфейс) в виде набора функций, классов, констант. То есть, проще говоря, модуль предоставляет нам какой-то новый функционал, новые возможности, которые мы могли бы реализовать сами, потратив… ну, скажем, несколько месяцев (а то и лет) на разработку, доводку и избавление от лажи (отлаживание). Скажем спасибо товарищам из Python Software Foundation за огромное количество модулей, которыми они снабдили своё творение.

 

Для наших целей понадобится всего два дополнительных модуля – один, под названием urllib, будет работать с сетью, скачивая файл, а другой (os) – с операционной системой, этот файл запуская. Модули традиционно подключаются к программе в самом начале командой import, после чего обращаться к функциям модуля можно так:

# -*- coding: cp1251 -*-

import math

print 'Sinus pi na dva raven = ', math.sin(math.pi/2)

                    

                     При желании, некоторые функции из модуля можно вынести в пространство переменных самой программы, что, согласитесь, удобнее.

 

# -*- coding: cp1251 -*-

from math import sin, cos, pi

print 'Sinus pi na dva raven = ', sin(pi/2)

 

 

            Какой вариант выберем? Давайте первый – функций-то не так и много… всего две))) Итак, импортируем (подключаем) модули:

 

# -*- coding: cp1251 -*-

 

# Подключаем необходимые модули

import urllib2

import os

 

            3) Этап загрузки. У модуля urllib2 есть функция urlopen(), которая делает запрос на сервер и возвращает нам объект, по структуре аналогичный обычной файловой переменной

print "Подождите! Загружаю файл!"

# Открываем нужный адрес - делаем на него запрос.

request = urllib2.urlopen("http://info.weather.yandex.net/baikonur/1.png")

 

Ах да… Вы же ещё не знаете что такое файловая переменная. Рассказываю.

 

 

 

Запись и чтение файлов

 

Функция open() возвращает объект файла и в большинстве случаев используется с двумя аргументами: open(имя_файла, режим).

 

>>> f = open('/tmp/workfile', 'w')

 

Первый параметр — строка, содержащая имя файла. Второй — другая строка, содержащая несколько символов, описывающих способ использования файла. Значение параметра режим может быть символом 'r', если файл будет открыт только для чтения, 'w' — открыт только для записи (существующий файл с таким же именем будет стёрт) и 'a' — файл открыт для добавления: любые данные, записанные в файл автоматически добавляются в конец. 'r+' открывает файл и для чтения, и для записи. Параметр режим необязателен: если он опущен — предполагается, что он равен 'r'.

 

В обычном случае файлы открываются в текстовом режиме (text mode) — это значит что вы читаете из файла и записываете в файл строки в определённой кодировке (по умолчанию используется UTF-8). Если добавить к режиму файла символ ‘b’, файл открывается в двоичном режиме (binary mode): теперь данные считываются и записываются в виде двоичных объектов. Этот режим следует использовать для всех файлов, которые не содержат текст.

 

При использовании текстового режима, все окончания строк, по умолчанию, специфичные для платформы (\n в Unix, \r\n в Windows) усекаются до символа \n, при чтении из файла, и конвертируются обратно из \n в вид, специфичный для платформы, при записи в файл. Эти закулисные изменения в файловых данных корректно работают в случае текстовых файлов, но испортят двоичные данные в файлах вроде JPEG или EXE. Внимательно следите за тем, чтобы использовать двоичный режим при чтении и записи таких файлов.

 

Методы объектов-файлов

 

В примерах ниже подразумевается, что заранее создан файловый объект с именем f.

 

Чтобы прочитать содержимое файла, вызовите f.read(размер) — функция читает некоторое количество данных и возвращает их в виде строки или байтового объекта. размер — необязательный числовой параметр. Если размер опущен или отрицателен, будет прочитано и возвращено всё содержимое файла; если файл по величине в два раза больше оперативной памяти вашего компьютера, то решение этой проблемы остаётся на вашей совести. В противном случае, будет прочитано и возвращено максимум размер байт. Если был достигнут конец файла, f.read() вернёт пустую строку ().

>>> f.read()

'Это всё содержимое файла.\n'

>>> f.read()

''

 

f.readline() читает одну строку из файла; символ новой строки (\n) остаётся в конце прочитанной строки и отсутствует при чтении последней строки файла только если файл не оканчивается пустой строкой. За счёт этого возращаемое значение становится недвусмысленным: если f.readline() возвращает пустую строку — достигнут конец файла, в то же время незаполненная строка, представленная посредством '\n', содержит лишь символ новой строки.

>>> f.readline()

'Это первая строка файла.\n'

>>> f.readline()

'Вторая строка файла\n'

>>> f.readline()

''

 

f.readlines() возвращает список, содержащий все строки с данными, обнаруженные в файле. Если передан необязательный параметр подсказка_размера, функция читает из файла указанное количество байт, плюс некоторое количество байт сверх того, достаточное для завершения строки, и формирует список строк из результата. Функция часто используется для более эффективного (файл не загружается в память полностью) построчного чтения больших файлов. Возвращены будут только полные (завершённые) строки.

>>> f.readlines()

['Это первая строка файла.\n', 'Вторая строка файла\n']

 

Альтернативный способ построчного чтения - организация цикла по файловому объекту. Он быстр, рационально использует память и имеет простой код в результате:

>>> for line in f:

        print(line, end='')

 

Это первая строка файла.

Вторая строка файла

 

Альтернативный способ проще, но не предоставляет тонкого контроля над происходящим. Поскольку оба этих способа работают с буферизацией строк по-разному, их не следует смешивать.

 

f.write(строка) записывает содержимое строки в файл и возвращает количество записанных байтов.

>>> f.write('This is a test\n')

15

 

Чтобы записать в файл нечто отличное от строки, предварительно это нечто нужно в строку сконвертировать:

>>> value = ('ответ', 42)

>>> s = str(value)

>>> f.write(s)

18

 

f.tell() возвращает целое, представляющее собой текущую позицию в файле f, измеренную в байтах от начала файла. Чтобы изменить позицию объекта-файла, используйте f.seek(смещение, откуда). Позиция вычисляется прибавлением смещения к точке отсчёта; точка отсчёта выбирается из параметра откуда. Значение 0 параметра откуда отмеряет смещение от начала файла, значение 1 применяет текущую позицию в файле, а значение 2 в качестве точки отсчёта использует конец файла. Параметр откуда может быть опущен и по умолчанию устанавливается в 0, используя начало файла в качестве точки отсчёта.

>>> f = open('/tmp/workfile', 'rb+')

>>> f.write(b'0123456789abcdef')

16

>>> f.seek(5)     # Перейти к шестому байту в файле

5

>>> f.read(1)       

b'5'

>>> f.seek(-3, 2) # Перейти к третьему байту с конца

13

>>> f.read(1)

b'd'

 

При работе с текстовыми файлами (открытыми без символа b в строке режима), выполнять позиционирование (seek) позволяется только от начала файла (за исключением прокрутки в конец файла с использованием seek(0, 2)).

 

Когда вы закончили все действия над файлом, вызовите f.close() чтобы закрыть его и освободить все системные ресурсы, использованные при открытии этого файла. Все попытки использовать объект-файл после вызова f.close() приведут к возникновению исключения.

>>> f.close()

>>> f.read()

Traceback (most recent call last):

  File "<stdin>", line 1, in ?

ValueError: I/O operation on closed file

 

 

4) Теперь понятнее? Продолжим. Файл мы загрузили, теперь самое время его сохранить. Например на диск Це. Делается это так – вводится новая файловая переменная, и открывается на запись нужный файл. Если файла ещё нет, операционная система создаст пустой шаблон.

 

# Создаём файл для записи и связываем его с файловой переменной f

f = file("c:\\pogoda.png", "wb")

 

Заметки на полях: а почему, собственно, два слеша? Да потому что Python воспринимает символ, идущий за слешем, как управляющий. Например, \n будет воспринято как перевод строки, а \\ как… как слеш J

 

Записываем в этот файл содержимое объекта, который нам вернула urlopen()

 

# Записываем туда полученную ДАННЫЕ, возвращённые в ответ на наш запрос (картинку)

f.write(request.read())

# Закрывая, сохраняем.

f.close()

 

print "Готово!"

 

 

По сути, мы прочитали данные из первого файла, и тут же сохранили в другой. Вот только этот «другой», в отличие от первого, настоящий. И связан не с областью памяти, а с реальным файлом на диске.

 

5) Приятное сообщение «всё готово» толкает нас на следующий шаг. Теперь наша задача – открыть сохранённый файл ассоциированной с ним программой. Проще некуда – за выполнение системной команды отвечает функция system модуля os.

 

os.system("c:\\pogoda.png")

 

Команда может быть любой – от запуска плеера, до форматирования флешки утилитой format. Но у нас – более мирные цели – мы, если вы помните, пытаемся увидеть скачанное. Результат – вот он:

 

 

            Прогноз радует оптимистичностью – мы точно не замёрзнем. Апчхи!)

 

 

            Посмотрим что у нас получилось…

 

# -*- coding: cp1251 -*-

 

# Подключаем необходимые модули

import urllib2

import os

 

print "Подождите! Загружаю файл!"

# Открываем нужный адрес - делаем на него запрос.

request = urllib2.urlopen("http://info.weather.yandex.net/baikonur/1.png")

 

# Создаём файл для записи и связываем его с файловой переменной f

f = file("c:\\pogoda.png", "wb")

# Записываем туда полученную ДАННЫЕ, возвращённые в ответ на наш запрос (картинку)

f.write(request.read())

# Закрывая, сохраняем.

f.close()

 

print "Готово!"

 

os.system("c:\\pogoda.png")

 

            Здорово? Я тоже так считаю. Мои поздравления! Первая программа на Python заработала.

 

 

 

Практическое задание

 

1)      Партийное задание – прямо сейчас, не отходя далеко, переделать имеющуюся программу:

a.       Для cкачивания и воспроизведения музыкального файла. Сам файл – найти в Интернете. Для особо ленивых – ссылка: http://dlyanaroda.narod.ru/Beatlesesterday.mid

b.      Для копирования файла (любого, на ваш выбор) из одной папки в другую

c.       Для открывания странички odnoklassniki.ru в окне вашего любимого браузера (например, Оперы)

2)      Разобраться чем отличается бинарный режим работы с файлами от обычного, текстового.

3)      Скачать, сохранить и открыть с диска главную страницу Яндекса.

 

 

 

 

 

 

Hosted by uCoz