Python. Урок 12. Ввод-вывод данных. Работа с файлами
В уроке рассмотрены основные способы ввода и вывода данных в Python с использованием консоли, и работа с файлами: открытие, закрытие, чтение и запись.
Вывод данных в консоль
Один из самых распространенных способов вывести данные в Python – это напечатать их в консоли. Если вы находитесь на этапе изучения языка, такой способ является основным для того, чтобы быстро просмотреть результат свой работы. Для вывода данных в консоль используется функция print.
Рассмотрим основные способы использования данной функции.
>>> print("Hello") Hello >>> print("Hello, " + "world!") Hello, world! >>> print("Age: " + str(23)) Age: 23
По умолчанию, для разделения элементов в функции print используется пробел.
>>> print("A", "B", "C") A B C
Для замены разделителя необходимо использовать параметр sep функции print.
print("A", "B", "C", sep="#") A#B#C
В качестве конечного элемента выводимой строки, используется символ перевода строки.
>>> for i in range(3): print("i: " + str(i)) i: 0 i: 1 i: 2
Для его замены используется параметр end.
>>> for i in range(3): print("[i: " + str(i) + "]", end=" -- ") [i: 0] -- [i: 1] -- [i: 2] --
Ввод данных с клавиатуры
Для считывания вводимых с клавиатуры данных используется функция input().
>>> input() test 'test'
Для сохранения данных в переменной используется следующий синтаксис.
>>> a = input() hello >>> print(a) hello
Если считывается с клавиатуры целое число, то строку, получаемую с помощью функции input(), можно передать сразу в функцию int().
>>> val = int(input()) 123 >>> print(val) 123 >>> type(val) class 'int'>
Для вывода строки-приглашения, используйте ее в качестве аргумента функции input().
>>> tv = int(input("input number: ")) input number: 334 >>> print(tv) 334
Преобразование строки в список осуществляется с помощью метода split(), по умолчанию, в качестве разделителя, используется пробел.
>>> l = input().split() 1 2 3 4 5 6 7 >>> print(l) ['1', '2', '3', '4', '5', '6', '7']
Разделитель можно заменить, указав его в качестве аргумента метода split().
>>> nl = input().split("-") 1-2-3-4-5-6-7 >>> print(nl) ['1', '2', '3', '4', '5', '6', '7']
Для считывания списка чисел с одновременным приведением их к типу int можно воспользоваться вот такой конструкцией.
>>> nums = map(int, input().split()) 1 2 3 4 5 6 7 >>> print(list(nums)) [1, 2, 3, 4, 5, 6, 7]
Работа с файлами
Открытие и закрытие файла
Для открытия файла используется функция open(), которая возвращает файловый объект. Наиболее часто используемый вид данной функции выглядит так open(имя_файла, режим_доступа).
Для указания режима доступа используется следующие символы:
‘r’ – открыть файл для чтения;
‘w’ – открыть файл для записи;
‘x’ – открыть файл с целью создания, если файл существует, то вызов функции open завершится с ошибкой;
‘a’ – открыть файл для записи, при этом новые данные будут добавлены в конец файла, без удаления существующих;
‘b’ – бинарный режим;
‘t’ – текстовый режим;
‘+’ – открывает файл для обновления.
По умолчанию файл открывается на чтение в текстовом режиме.
У файлового объекта есть следующие атрибуты.
file.closed – возвращает true если файл закрыт и false в противном случае;
file.mode – возвращает режим доступа к файлу, при этом файл должен быть открыт;
file.name – имя файла.
>>> f = open("test.txt", "r") >>> print("file.closed: " + str(f.closed)) file.closed: False >>> print("file.mode: " + f.mode) file.mode: r >>> print("file.name: " + f.name) file.name: test.txt
Для закрытия файла используется метод close().
Чтение данных из файла
Чтение данных из файла осуществляется с помощью методов read(размер) и readline().
Метод read(размер) считывает из файла определенное количество символов, переданное в качестве аргумента. Если использовать этот метод без аргументов, то будет считан весь файл.
>>> f = open("test.txt", "r") >>> f.read() '1 2 3 4 5\nWork with file\n' >>> f.close()
В качестве аргумента метода можно передать количество символом, которое нужно считать.
>>> f = open("test.txt", "r") >>> f.read(5) '1 2 3' >>> f.close()
Метод readline() позволяет считать строку из открытого файла.
>>> f = open("test.txt", "r") >>> f.readline() '1 2 3 4 5\n' >>> f.close()
Построчное считывание можно организовать с помощью оператора for.
>>> f = open("test.txt", "r") >>> for line in f: . print(line) . 1 2 3 4 5 Work with file >>> f.close()
Запись данных в файл
Для записи данных файл используется метод write(строка), при успешной записи он вернет количество записанных символов.
>>> f = open("test.txt", "a") >>> f.write("Test string") 11 >>> f.close()
Дополнительные методы для работы с файлами
Метод tell() возвращает текущую позицию “условного курсора” в файле. Например, если вы считали пять символов, то “курсор” будет установлен в позицию 5.
>>> f = open("test.txt", "r") >>> f.read(5) '1 2 3' >>> f.tell() 5 >>> f.close()
Метод seek(позиция) выставляет позицию в файле.
>>> f = open("test.txt", "r") >>> f.tell() 0 >>> f.seek(8) 8 >>> f.read(1) '5' >>> f.tell() 9 >>> f.close()
Хорошей практикой при работе с файлами является применение оператора with. При его использовании нет необходимости закрывать файл, при завершении работы с ним, эта операция будет выполнена автоматически.
>>> with open("test.txt", "r") as f: . for line in f: . print(line) . 1 2 3 4 5 Work with file Test string >>> f.closed True
P.S.
Если вам интересна тема анализа данных, то мы рекомендуем ознакомиться с библиотекой Pandas. На нашем сайте вы можете найти вводные уроки по этой теме. Все уроки по библиотеке Pandas собраны в книге “Pandas. Работа с данными”.
>>
Раздел: Python Уроки по Python Метки: Python, Уроки Python
Python. Урок 12. Ввод-вывод данных. Работа с файлами : 2 комментария
- Моксим23.11.2020 “Преобразование строки в список осуществляется с помощью метода split(), по умолчанию, в качестве разделителя, используется пробел.”
Разделитель по умолчанию не пробел, а пустое пространство
- Алексей 01.06.2021 Ого, действительно:
>>> “1 2 3 4 5 7”.split()
[‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘7’]
И даже так:
>>> “1 2 \n 21 12 4”.split()
[‘1’, ‘2’, ’21’, ’12’, ‘4’]
Как вызвать функцию из другого файла .py
Введение Часто при написании программ на Python возникает ситуация, когда функции или классы, объявленные в одном файле, требуется использовать в другом.
Алексей Кодов
Автор статьи
7 июля 2023 в 18:02
Введение
Часто при написании программ на Python возникает ситуация, когда функции или классы, объявленные в одном файле, требуется использовать в другом. Это может быть необходимым, например, при организации кода по модулям для повышения его читаемости и упрощения сопровождения.
Рассмотрим простой пример. Пусть у нас есть файл functions.py , в котором определена функция:
# functions.py def greet(name): print(f"Hello, !")
И мы хотим вызвать эту функцию в другом файле, например, main.py .
Ошибка при импорте
Наиболее распространенной ошибкой при попытке вызвать функцию из другого файла является ошибка ImportError: No module named ‘file.py’; file is not a package . Она возникает, когда мы пытаемся импортировать функцию следующим образом:
from functions.py import greet
Правильный способ импорта
Ошибка возникает из-за некорректного использования синтаксиса импорта. В Python при импорте модулей расширение .py не указывается. Правильный способ импортировать функцию из другого файла выглядит следующим образом:
from functions import greet
Теперь функцию greet можно вызвать в файле main.py так:
greet("World")
При выполнении этого кода в консоли будет выведено сообщение «Hello, World!».
Вывод
Итак, для вызова функции из другого файла в Python необходимо использовать ключевое слово import без указания расширения файла. Это позволяет организовать код более структурированно, выделяя логически связанные функции и классы в отдельные файлы.
Загрузка файлов на сервер модулем requests в Python
Для понимания этого материала необходимо ознакомиться с передачей дополнительных параметров в запросе методом POST, который представлен в ознакомительной статье к библиотеке requests .
- Отправка одного файла на сервер.
- Отправка нескольких файлов на сервер.
Отправка одного файла на сервер.
Библиотека requests упрощает загрузку файлов на сервер с многосоставной кодировкой Multipart-encoded . Для этого, в словарь с дополнительными параметрами POST запроса необходимо добавить ключ ‘file’ , а в качестве его значения указать объект открытого файла с помощью функции open() в двоичном режиме ‘rb’ :
Сразу смотрим пример:
>>> import requests # целевой URL-адрес >>> url = 'https://httpbin.org/post' # открываем файл на чтение в # бинарном режиме ('rb') >>> fp = open('report.xls', 'rb') # помещаем объект файла в словарь # в качестве значения с ключом 'file' >>> files = 'file': fp> # передаем созданный словарь аргументу `files` >>> resp = requests.post(url, files=files) >>> fp.close() >>> resp.text # # . # "files": # "file": "" # >, # . # >
Можно явно указать имя файла, content_type и другие заголовки в значении ключа file создаваемого словаря, для передачи файла на сервер:
>>> import requests >>> url = 'https://httpbin.org/post' >>> fp = open('report.xls', 'rb') # указываем дополнительные заголовки и параметры >>> files = 'file': ('report.xls', fp, 'application/vnd.ms-excel', 'Expires': '0'>)> >>> resp = requests.post(url, files=files) >>> fp.close() >>> resp.text # # . # "files": # "file": "" # >, # . # >
При желании, вместо самого файла можно отправить строку, представляющую контент файла:
>>> import requests >>> url = 'https://httpbin.org/post' >>> files = 'file': ('report.csv', 'some, data, to, send\nanother, row, to, send\n')> >>> resp = requests.post(url, files=files) >>> resp.text # # . # "files": # "file": "some,data,to,send\\nanother,row,to,send\\n" # >, # . # >
Отправка нескольких файлов на сервер.
Постоянно возникают ситуации, когда необходимо отправить несколько файлов на сервер в одном запросе. Например, предположим, что надо загрузить файлы изображений в HTML-форму с несколькими полями из файлов изображений .png :
input type="file" name="images" multiple="true" required="true"/>
Для этого просто передаем файловые объекты (предварительно открытые функцией open() в двоичном режиме ‘rb’ ) в список кортежей следующего вида (form_field_name, file_info) :
>>> import requests # целевой адрес с формой отправки >>> url = 'https://httpbin.org/post' # добавляем файловые объекты в список кортежей >>> multiple_files = [ . ('images', ('foo.png', open('foo.png', 'rb'), 'image/png')), . ('images', ('bar.png', open('bar.png', 'rb'), 'image/png'))] # делаем запрос >>> resp = requests.post(url, files=multiple_files) >>> resp.text . 'files': 'images': 'data:image/png;base64,iVBORw . '> 'Content-Type': 'multipart/form-data; boundary=31316. ', . >
Предупреждение. Настоятельно рекомендуется открывать файлы в двоичном режиме ‘rb’ . Это связано с тем, что запросы могут попытаться предоставить заголовок Content-Length , и если это произойдет, то это значение будет установлено на количество байтов в файле. При открытии файла в текстовом режиме могут возникнуть ошибки.
- КРАТКИЙ ОБЗОР МАТЕРИАЛА.
- GET и POST запросы c модулем requests
- Получение/отправка заголовков сервера модулем requests
- Извлечение и установка cookies с модулем requests
- Сессии/сеансы Session() модуля requests
- Объект ответа сервера Response модуля requests
- Получение и отправка данных в виде JSON с модулем requests
- Установка timeout для модуля requests
- Объект PreparedRequest модуля requests
- Загрузка файлов на сервер модулем requests
- Загрузка больших данных модулем requests
- HTTP-прокси или SOCKS-прокси с модулем requests
- Использование хуков модуля requests
- Аутентификация с модулем requests
- SSL и модуль requests
Потоки. Передача файлов. Клиент-серверный чат¶
Потоки (thread) в Python позволяет одновременно запускать разные подпрограммы, таким образом становится возможно выполнять несколько подпрограмм в одно и то же время. thread — это отдельный поток выполнения.
На самом деле подпрограммы даже при использовании потоков не выполняются одновременно:
- Работа с потоками — это не работа с разными ядрами процесса, мы фактически работаем внутри того же процесса, что и без потоков, только дробим его на подзадачи, так что о более эффективном распределении ресурсов речи не идёт.
- В Python для обеспечения стабильности и снижения конфликтов работает специальный шлюз — Global Interpreter Lock (GIL). Он и контролирует потоки.
GIL переключает потоки по умолчанию раз в 5 миллисекунд, так что потоки работают не одновременно, а последовательно, постоянно сменяя друга.
Самая близкая идея работе потоков в Питоне — сеанс одновременной игры в шахматы, когда один шахматист играет с несколькими. Сеанс хоть и называется “одновременным”, но фактически шахматист обходит всех по очереди и делает свой ход в каждой партии.
Для работы с потоками используются модули _thread и threading (более новый).
Рассмотрим простой код для работы с потоками.:
import threading import time def thread_function(number): print(f"Thread number>: starting\n") time.sleep(2) print(f"Thread number>: finishing\n") threads = list() for index in range(3): print(f"Create and start thread index>\n") x = threading.Thread(target=thread_function, args=(index,)) threads.append(x) x.start() for i,thread in enumerate (threads): print (f'Join thread i> \n') thread.join()
Передача файлов¶
- Настраиваем сокет, устанавливаем соединение.
- На отправляющей стороне:
- открываем файл на чтение в режиме байтового чтения ( ‘rb’ ).
- построчно передаём файл принимающей стороне.
- На принимающей стороне:
- открываем файл на запись в режиме байтовой записи ( ‘wb’ ).
- построчно пишем в файл всё, что получаем от передающей стороны.
- Закрываем файлы и соединение.
Передача файлов байтовыми строками позволяет пересылать любые файлы, независимо от их типа, расширения и т.п.
Пример кода для отправки файла с клиента серверу.
import socket import sys # создаём сокет и связываем его с IP-адресом и портом sock = socket.socket() ip = "localhost" port = 9999 sock.bind((ip, port)) # сервер ожидает передачи информации sock.listen(10) while True: # начинаем принимать соединения conn, addr = sock.accept() # выводим информацию о подключении print('connected:', addr) # получаем название файла name_f = (conn.recv(1024)).decode ('UTF-8') # открываем файл в режиме байтовой записи в отдельной папке 'sent' f = open('sent/' + name_f,'wb') while True: # получаем байтовые строки l = conn.recv(1024) # пишем байтовые строки в файл на сервере f.write(l) if not l: break f.close() conn.close() print('File received') sock.close()
import socket import sys ip = "localhost" port = 9999 # создаём сокет для подключения sock = socket.socket() sock.connect((ip,port)) # запрашиваем имя файла и отправляем серверу f_name = input ('File to send: ') sock.send((bytes(f_name, encoding = 'UTF-8'))) # открываем файл в режиме байтового чтения f = open (f_name, "rb") # читаем строку l = f.read(1024) while (l): # отправляем строку на сервер sock.send(l) l = f.read(1024) f.close() sock.close()
Задания¶
- Используя код из урока, реализуйте возможность отправлять файл с сервера клиенту.
- Реализуйте возможность передачи файлов как от клиента серверу, так и от сервера клиенту:
- должна быть возможность выбрать режим передачи (1 — от клиента серверу, 2 — от сервера клиенту);
- оформите код с помощью функций;
- добавьте графический интерфейс с помощью модуля easygui.
- Используя потоки напишите клиент-серверный чат, который будет принимать и отправлять сообщения. Для этого потребуется оформить код в функции.
© Copyright Revision 07b34d26 .
Built with Sphinx using a theme provided by Read the Docs.
Read the Docs v: latest
Versions latest Downloads html On Read the Docs Project Home Builds Free document hosting provided by Read the Docs.