Методичка. Методические указания по ПО АС_очники. Методические указания к проведению занятий по дисциплине " Программное обеспечение автоматизированных систем" Москва 2018
Скачать 0.59 Mb.
|
Тема 6. Ввод-вывод данных и операции с файламиЦель работы: Научиться работать с файловым устройством в качестве накопителя или источника данных для проведения расчетов. Запустите интерактивную оболочку IDLE. Откройте окно текстового редактора. В первой строке напишите комментарий с текстом: « Тема 6 <ФИО>». Сохраните содержимое окна редактора в своем рабочем каталоге с именем файла протокола. В ходе выполнения дальнейшей работы все корректно выполненные инструкции и их результаты записывайте в этот текстовый файл. Операции ввода и вывода данных являются важной частью любой программы, обеспечивающей её информационное взаимодействие с «внешним миром». Здесь будет изучаться программирование такого взаимодействия с пользователем и с файловым устройством. Вывод данных на экран дисплея. 2.1. Вывод в командной строке. Пока вы работаете не с программой, а с инструкциями, вводимыми в командной строке интерпретатора или среды IDLE, содержимое любого объекта можно увидеть простым упоминанием его в командной строке (как это много раз делалось раньше), например, stroka='Автоматизированная система управления' stroka Этот способ называется «эхо-выводом». Он пригоден при работе в командной строке, однако в пользовательских функциях этот способ применять нельзя! 2.2.Вывод с использованием функции print. Этот способ можно применять и в командной строке, и в функциях, поэтому привыкайте использовать только его! По умолчанию вывод будет осуществляться на экран, но, как увидим дальше, пункт назначения выводимых данных можно переопределить. Пример вывода: fff=234.5;gg='Значение температуры = ' print(gg, fff) #Можно вывести несколько объектов за одно обращение к функции По умолчанию выводимые объекты разделяются одним пробелом. Если нужен другой разделитель его можно указать в отдельном аргументе sep, например, print(gg, fff, sep='/') После вывода автоматически осуществляется переход на другую строку. Если курсор надо оставить в той же строке, то следует использовать еще один аргумент, например, print(gg, fff,sep='/',end='***'); print('____') После end= надо указать какими символами должна закончиться выводимая строка или указать пустую строку. Наоборот, если в какой-то момент требуется просто перейти на новую строку, можно использовать такое обращение к функции: print() Наконец, оператор вывода может располагаться на нескольких строках с использованием тройных кавычек print(""" Здесь может выводиться большой текст, занимающий несколько строк""") или print("Здесь может выводиться", "большой текст,", "занимающий несколько строк") Обратите внимание на различие в получающемся результате. При выводе русскоязычных символов по инструкции print могут возникнуть проблемы с кодировкой. Особенно часто это бывает при выводе из импортируемых пользовательских программных модулей (см.тему 7). Для преодоления этих проблем в начале модуля следует указать кодировку с помощью псевдокомментария, например: # -*- coding: utf-8 -*- 2.3. Вывод с использованием метода write объекта sys.stdout. Объект stdout представляет собой поток стандартного вывода – объект, в который программы выводят символьное представление данных. Обычно это – экран дисплея. Объект находится в модуле sys, который надо импортировать. Например, import sys sys.stdout.write('Функция write') Обратите внимание, что этот метод после вывода строки не осуществляет переход на новую строку. Если это требуется, то следует в конце строки добавить один или несколько символов “\n”: sys.stdout.write('Функция write\n') Ввод данных с клавиатуры. Для ввода используйте уже знакомую функцию input. Например: psw=input('Введите пароль:') Введите в ответ на запрос любую комбинацию символов и потом проверьте, что эта комбинация стала значением переменной psw. Посмотрите, какой тип у этой переменной? Пример 1. Ввод с контролем значения. Пусть вводится число, которое должно находиться в интервале значений от 17.5 до 23.8. while True: znach=float(input('Задайте коэф.усиления = ')) if znach<17.5 or znach>23.8: print('Ошибка!') else: break Попробуйте применить эти инструкции со вводом значения 15.4, а затем: 21.6. Пример 2. Ввод и обработка выражения, подлежащего расчету. import math print(eval(input('введите выражение для расчета = '))) В ответ на запрос введите, например, выражение: math.log10(23/(1+math.exp(-3.24))). Какой получился результат? Ввод-вывод при работе с файлами. Работа с файлом требует указания источника данных - полного имени файла с путем доступа к его расположению. Обычно наибольшие затруднения вызывает корректная локализация этого пути. 4.1. Функции для работы с путем к файлу. Эти функции собраны в модуле os. Поэтому при работе с файлами надо импортировать этот модуль командой import os Как и в других системах, в среде Python в любой момент времени подразумевается некоторый рабочий каталог. Какой рабочий каталог установлен в текущий момент времени? Это можно узнать с помощью функции os.getcwd (cwd = current working directory) os.getcwd() Сохраните этот путь в переменной с именем, совпадающим с вашей фамилией в латинской транскрипции. Отобразите её значение с помощью функции print. Обратите внимание на то, что в получаемой символьной строке компоненты пути разделяются двойными обратными слэшами: «\\». Как обычно, при работе с файлами, размещенными в рабочем каталоге, путь доступа к ним можно не указывать. В начале сеанса работы со средой Python в качестве рабочего каталога по умолчанию устанавливается путь к каталогу, в котором был установлен Python, например, 'C:\\Python34'. При запуске из текстового редактора IDLE программы, находящейся в некотором файле, за рабочий каталог принимается тот, в котором расположен файл с программой. Изменить расположение рабочего каталога можно обращением к уже многократно применявшейся функции os.chdir, аргументом которой будет символьная строка с указанием пути к каталогу, назначаемому в качестве рабочего, например, os.chdir('d:\\users\\tmp5\\') При вводе пути в командной строке IDLE для удобства пользователей после указания очередного каталога будет выдаваться список всех вложенных в него подкаталогов, что позволяет заменить ввод имени подкаталога простым выбором из списка. Кстати, стимулировать вывод этого списка можно нажатием клавиши TAB. Обратите внимание на то, что и здесь имена каталогов в пути должны разделяться двойными обратными слэшами. Для контроля вновь выведите положение установленного рабочего каталога с помощью уже известной функции getcwd. Самостоятельно изучите и попробуйте использовать следующие функции из модуля os: mkdir, rmdir, listdir и функцию isdir из вложенного в os модуля os.path. Пусть в рабочем каталоге находится файл OPLATA.DBF. С помощью функции os.path.abspath можно получить символьную строку, содержащую имя файла вместе с полным путем доступа к нему: fil=os.path.abspath("oplata.dbf") Попробуйте применить эту функцию к любому файлу из рабочего каталога. Выделите путь доступа к файлу из строки, содержащей и этот путь, и имя файла с помощью функции os.path.dirname: drkt=os.path.dirname(fil) Наоборот, выделить имя файла из этой строки с отбрасыванием пути можно с помощью функции os.path.basename. Попробуйте использовать эту функцию. Также самостоятельно изучите функцию os.path.split. Какое значение возвращает эта функция? С помощью функции os.path.exists можно проверить существует ли путь, заданный в символьной строке – аргументе функции. Возвращаемое значение: True или False. Попробуйте применить её с существующим и несуществующим путями. Проверьте наличие файла с известным расположением с помощью функции os.path.isfile, аргументом которой должна быть символьная строка с путем и именем интересующего файла. Возвращаемое значение: True или False. Эту функцию в дальнейшем рекомендуется использовать до того, как будет сделана попытка открыть файл для чтения. Например, os.path.isfile(fil) или os.path.isfile(os.path.dirname(fil)+'fil1.txt') Общая схема работы с файлом Для обмена данными с файлом необходимо выполнить следующие операции: Открытие файла с указанием его имени и цели (чтение, запись, добавление данных); Выполнение одной или нескольких операций обмена данными с файлом; Закрытие файла. Открытие файла для записи или чтения данных – функция open. При открытии файла необходимо указать имя файлы (с путем, если он не в рабочем каталоге) и цель работы с ним. Для открытия используется функция open. Запросите помощь по этой функции, обратите внимание на возможные аргументы этой функции. Откройте файл zapis1.txt для записи данных с помощью инструкции fp=open(file=drkt+'\\zapis1.txt',mode='w') Здесь fp – это файловый объект, который в других языках программирования обычно называют файловой переменной. Он сохраняет ссылку на открываемый файл и позволяет в дальнейшем ссылаться на файл, не указывая путь и имя открытого файла. В аргументе функции с именем file указывается путь и имя открываемого файла, а в аргументе с именем mode – предполагаемая цель его использования (w=write – для записи). Вообще говоря, аргументы функции с их именами могут располагаться в любом порядке. Если имя файла располагается на месте первого аргумента, а цель использования – на втором, то имена аргументов можно не указывать и просто вводить fp=open(drkt+'\\zapis1.txt','w') Если путь в переменной drkt совпадает с рабочим каталогом, то его можно опустить, оставив только имя открываемого файла: fp=open('zapis1.txt','w') Отобразите тип и список атрибутов объекта fp. Файл по такой инструкции открывается только для записи в файл. Если требуются другие операции с открываемым файлом, то для второго аргумента «mode=…» могут быть заданы следующие значения: w – запись с созданием нового файла или перезапись существующего файла, w+ - чтение и запись/перезапись файла, r – только чтение (это значение - по умолчанию), r+ - чтение и/или запись в существующий файл, a – запись в конец существующего файла или, если его нет, запись с созданием файла, a+ - то же, что и в «a», но с возможностью чтения из файла. В зависимости от значения этого аргумента тип создаваемой файловой переменной может быть разным. Создаваемые и читаемые файлы могут быть бинарными или символьными. При открытии бинарного файла к указанным выше буквам в аргументе-цели надо добавить символ «b». Например, fp1=open(drkt+'\\zapis2.bin',mode='wb+') В бинарный файл можно без преобразования записывать объекты любого типа. Если файл – символьный, то его тип обозначается «t», но это – значение по умолчанию и его можно не указывать. В символьный файл можно записывать только объекты типа str. Объекты других типов надо перед записью преобразовать к этому типу. Как и раньше, используйте строку drkt с указанием каталога только при обмене данными с файлом вне рабочего каталога. Закрытие файла. Сразу после завершения работы с файлом его следует закрыть для обеспечения сохранности его содержимого. Это делается с помощью метода close, применяемого к объекту – файловой переменной. Например, fp.close() Запись информации в файл с помощью метода write. Метод write относится к объекту – файловой переменной. Рассмотрите его применение на следующем примере: создайте список с элементами-числами от 1 до 12 и запишите их в файл по 4 числа на строке: sps=list(range(1,13) fp2=open('zapis3.txt','w') fp2.write(str(sps[:4])+'\n') fp2.write(str(sps[4:8])+'\n') fp2.write(str(sps[8:])+'\n') fp2.close() Откройте файл zapis3.txt в текстовом редакторе и изучите его содержимое. Ещё один пример. Создайте список с элементами-списками: sps3=[['Иванов И.',1],['Петров П.',2],['Сидоров С.',3]] Пусть его элементы требуется построчно записать в файл zapis4.txt. Первая попытка: fp3=open('zapis4.txt','w') for i in range(len(sps3)): stroka4=sps3[i][0]+' '+str(sps3[i][1]) fp3.write(stroka4) fp3.close() Откройте получившийся файл в текстовом редакторе, посмотрите на его содержимое и сохраните его в протоколе работы. Легко заметить, что информация записана в файл не очень удачно. Тогда попробуйте сделать так: gh=open('zapis5.txt','w') for r in sps3: gh.write(r[0]+' '+str(r[1])+'\n') gh.close() Обратите внимание на то, что этот цикл можно представить одной строкой: for r in sps3: gh.write(r[0]+' '+str(r[1])+'\n') Ещё раз посмотрите на содержимое файла – что изменилось? Первый способ чтения информации из текстового файла. Информация в текстовом файле размещена последовательно, по строкам, с завершением каждой строки символом ‘\n’ (конец строки). При чтении из файла из него извлекается часть информации, начиная с некоторого символа. Обычно, для удобства, считают, что перед этим символом стоит невидимый маркер (указатель), который при открытии файла устанавливается перед первым символом. После чтения части информации маркер перемещается и ставится перед символом, следующим за прочитанной частью информации. Прочитайте информацию из ранее созданного файла zapis3.txt. sps1=[] fp=open('zapis3.txt') for stroka in fp: stroka=stroka.rstrip('\n') stroka=stroka.replace('[','') stroka=stroka.replace(']','') sps=sps+stroka.split(',') fp.close() Обратите внимание, что в функции открытия файла использован только один аргумент, остальные – со значениями «по умолчанию». Здесь, перед занесением строки в список с помощью метода rstrip, из неё удаляется символ конца строки, а с помощью метода replace – скобки. Обратите также внимание на то, чем отличается полученный список от списка sps, использованного при создании файла zapis3.txt. Подумайте, как сделать так, чтобы список, полученный при чтении из файла, совпал с исходным. Чтение информации из файла с помощью метода read. Метод read, как и write, относится к объекту – файловой переменной. В качестве аргумента этого метода может задаваться целое число – количество символов или, если открыт бинарный файл, - количество байт, которое должно быть прочитано, соответственно, из текстового или бинарного файла, начиная с текущего положения маркера. Если указанное число превышает количество оставшихся символов (байт) в файле, то считываются все оставшиеся символы (байты). Если это число не указано, то считываются вся информация от маркера до конца файла. Метод возвращает строку с символами или совокупность байт, прочитанных из файла. Например, fp=open('zapis3.txt') stroka1=fp.read(12) stroka2=fp.read() fp.close() Отобразите объекты stroka1, stroka2 на экране. Чтение информации с помощью методов readline и readlines. Эти методы позволяют прочитать из файла, начиная с текущего положения маркера, соответственно, одну строку символов (совокупность байт) или все строки (все байты). Изучите их применение самостоятельно. Ввод-вывод объектов с использованием функций из модуля pickle. В модуле pickle содержатся функции для работы с бинарными файлами, в которые могут последовательно записываться или считываться целиком один или несколько объектов из оперативной памяти. Рассмотрите этот способ работы с файлами на следующем примере: import pickle mnoz1={'pen','book','pen','iPhone','table','book'} #Объект типа «множество» fp=open('zapis6.mnz','wb') # Бинарный файл – на запись pickle.dump(mnoz1,fp) #dump – метод записи объекта в файл fp.close() Попробуйте открыть файл zapis6.mnz в текстовом редакторе и убедитесь, что он – бинарный. Теперь прочитайте данные из файла в объект mnoz2: fp=open('zapis6.mnz','rb') mnoz2=pickle.load(fp) #load – метод чтения объекта из бинарного файла fp.close() Выведите объект на экран и убедитесь, что он содержит информацию из mnoz1. Объясните, почему он не совпадает с тем, что было задано при создании mnoz1. Проверьте два объекта: mnoz1 и mnoz2 на совпадение. А теперь с использованием тех же функций запишите в файл, а затем прочитайте два объекта разных типов: то же множество mnoz1 и ранее созданный список sps3. При считывании объекты извлекаются из файла в той же последовательности, в которой они в него записывались. fp=open('zapis7.2ob','wb') pickle.dump(mnoz1,fp) pickle.dump(sps3,fp) fp.close() fp=open('zapis7.2ob','rb') obj1=pickle.load(fp) #Первое обращение к load читает первый объект obj2=pickle.load(fp) #Второе – читает второй fp.close() Выведите obj1 и obj2 на экран и убедитесь, что они совпадают, соответственно, с mnoz1 и sps3. Перенаправление потоков ввода и вывода данных. Проделайте следующие операции: import sys vr_out=sys.stdout #Запоминаем текущий поток вывода fc=open('Stroka.txt','w') #Откроем файл вывода sys.stdout=fc #Перенацеливаем стандартный поток вывода на файл print('запись строки в файл') #Вывод теперь будет не на экран, а в файл sys.stdout=vr_out #Восстановление текущего потока print('запись строки на экран') #Убеждаемся, что вывод на экран восстановился fc.close() В результате создан файл Stroka.txt в текущем каталоге с содержанием 'запись строки в файл' Точно также можно перенаправить поток ввода – sys.stdin – вместо клавиатуры – из файла. tmp_in = sys.stdin #Запоминаем текущий поток ввода fd = open("Stroka.txt", "r") #Открываем файл для ввода (чтения) sys.stdin = fd #Перенацеливаем ввод на файл вместо клавиатуры sys.stdin <_io.TextIOWrapper name='zapfile3.txt' mode='r' encoding='cp1251'> while True: try: line = input () #Считываем из файла строку print(line) # Отображаем считанное except EOFError: break В результате на экране должно отобразиться: запись строки в файл fd.close() sys.stdin=tmp_in #Не забыть вернуть стандартное назначение для потока ввода Сохраните созданный текстовый файл протокола в своем рабочем каталоге. Закончите сеанс работы с IDLE. Общее контрольное задание. Придумайте инструкции и запишите их в файл с расширением .py , которые выполняют следующие операции: Создаётся объект-кортеж со 125 целыми случайными числами из диапазона от 6 до 56, представленными в виде символьных строк. Создаётся объект-список с вашей фамилией и 4 фамилиями ваших одноклассников. Записывается кортеж в бинарный файл. Записывается в этот же файл список и закрывается файл. Открывается этот файл для чтения и считывает из него данные в 2 новых объекта. Проверяется на совпадение новых объектов с исходными и выводится соответствующее сообщение. Разделяется кортеж на совокупности по 5 чисел в каждой и записываются в виде отдельных списков. |