Работа с файлами и стандартные модули

Модули

Модулей в языке Python очень много, было бы полезно поглядеть в полный https://docs.python.org/3/py-modindex.html. Этот список включает в себя порядка 250 различных модулей, которые входят в базовую поставку, и можно считать, что они есть всегда.

Некоторые примеры:

- argparse - разбор аргументов командной строки

- array - работа с массивами (не списками, а именно с настоящими массивами)

- base64 - различные преобразования текста, кодирование и декодирование

- bz2 - упаковка и распаковка архивов с помощью архиватора bz2

- cgi - модуль для работы с вебом

- collections - набор типов данных, которых нет в базовом языке ( нипример, словарь, элементы которого элементы создавались по факту обращения к нему)

- ensurepip - модуль для установки и обновления pip

- gc - работа со сборщиком мусора

- getopt - разбор командной строки

- http - работат с http (например, создание http сервера)

- itertools - работа с итераторами

- locale - поддержка локализации

- os - интерфейс для работы с операционной системой

- pydoc - парсинг и показ документации по питону (может работать сервером, если на него зайти, то можно увидеть документацию по всем модулям)

- re - регулярные выражения

- select - работает с системным вызовом select и занимается эффективной обработкой различных потоков

- socket - поддержка сокетов

- sys - доступ к информации о самом питоне

- time - изменение и работа со временем

- venv - возможность вести разработку ПО на питоне, даже если используются различные можули (различные версии модулей)

Рекурсия

Глубина рекурсивных вызовов ограничена 1000, поэтому не стоит использовать рекурсию вместо цикла. К тому же, практически любую рекурсивную функцию можно написать в виде цикла

Пример варианта программы, написанной в виде цикла, и вариант в виде рекурсии:

'''
Ввести натуральное число N, вывести все различные разложения N на сомножители
без учёта порядка
'''

def demultR(N, m=2):
    k = m
    while N//k >= k:
        if N%k == 0:
            for res in demultR(N//k,k):
                yield (k,)+res
        k += 1
    yield (N,)

def demultP(N):
    stack = [[N,2,2]]                         # def demultR(N, m=2):
    while stack:                              #
        NS = stack[-1]                        # N, m, k
                                              # k = m
        if NS[0]//NS[2] >= NS[2]:             # while N//k >= k:
            if NS[0]%NS[2] == 0:              #     if N%k == 0:
                n,m,k=NS[0]//NS[2],NS[2],NS[2]#
                stack.append([n,m,k])         #         for res in demult(N//k,k):
                NS[2] += 1                    #
                continue                      #             yield (k,)+res
            NS[2] += 1                        #     k += 1
        else:                                 #
            ret = [s[1] for s in stack[1:]]   #
            yield ret+[NS[0]]                 # yield (N,)
            stack.pop()                       #

N = int(input())
for R,P in zip(demultR(N),demultP(N)):
    print(*R, "/", *P)

Вызов функции - довольно тяжелая операция, связанная с создание пространства имен, созданием и удалением объектов, поэтому рекомендуется использовать рекурсию только там, где она необходима.

Работа с файлами

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

31.32.png

По умолчанию питон открывает файлы как текстовые, преобразуя их их формата хранения в текущую кодировку и обратно

f.name - имя файла

По операции read() все содержимое файлы считывается в строковом формате и связывается с именем s

34.04.png

Если еще раз выполнить операцию read(), то она вернет пустую строчку. Это значит, что файл кончился.

Можно прочитать из файла не все, а только 10 байт

34.37.png

Замечание: При чтении после конца файла, он возвращает не ошибку, не специальный признак конца файла, а пустую строку.

Можно открыть файл на запись, при этом в момент открытия файла на запись, все содержимое пропадает

f = open("oo", "w")

Запись в файл производится командой write(), которая возвращает количество записанных байт

f.write("abc")

Закрыть файл:

f.close()

Системная кодировка может отличаться в зависимости от системы, системный язык тоже определяется кодировкой, поэтому единственный способ сделать из содержимого файла питоновскую строку - перекодировать из одной кодировки в другую, что команда read() и делает.

Если просто открыть файл на чтение, то можно обнаружить, что он является итератором (__iter__):

40.23.png

Следовательно, его можно, например, превратить в список строк:

40.35.png

Это позваляет сделать следующее:

with open("table.py") as f:
    for s in f:
        print(s)

Замечание: файл даже не нужно будет закрывать, with сделает сам

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

Операция writelines() - запись строк в файл:

45.14.png

В итоге получится:

45.03.png

Операция readlines() - построчное чтение из файла:

46.00.png

Можно записать в файл питоновские объекты в формате Json, например словарь:

f = open("oo", "w")
json.dump({1:1, 2:6, "edfe":"efwef"}, f)
f.close()

Можно открыть бинарный файл:

f = open("oo", "wb")
f = open("oo", "rb")

С помощью модуля pickle можно записать в файл произвольный питоновский объкт:

import pickle
f = open("oo", "wb")
pickle.dump({1:1, 3:"dfe", "sefe":"efef"}, f)
pickle.dump(100500)
f.close()

Чтение из файла:

f = open("oo", "rb")
pickle.loads(f)

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

struct.pack() - упаковка

Пример:

1.09.00.png

Получим упакованную структуру из целого числа, числа с плавающей точкой и 10 байт. Подробное описание модуля struct можно найти тут.

Замечание: модуль struct не может определять объекты переменного размера.

Дополнение

Если в python написать import this, то получим

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Если набрать import antigravity:

1.png

LecturesCMC/PythonIntro2017/13_Misc/Conspect (последним исправлял пользователь AslanAshabokov 2018-01-01 21:26:15)