⇤ ← Версия 1 от 2020-11-24 12:46:52
2341
Комментарий:
|
6648
|
Удаления помечены так. | Добавления помечены так. |
Строка 36: | Строка 36: |
* `open()`, `r`/`w`/`a` и т. п. * `.read()`/`.write()`/`.readline()` * файл как итератор, `.readlines()` * `.seek()`,`.tell()` |
|
Строка 37: | Строка 41: |
* `str`, `bytes` и `bytearray` * файл как итератор * файл и `with` |
* повтор: `str`, `bytes` и `bytearray` * `b`/`t` * файл и `with`, зачем нужно |
Строка 43: | Строка 47: |
* Кодировка: соответствие некоторого числа конкретному символу (например, описанному в [[https://r12a.github.io/uniview/|Unicode]]) * Тысячи их * UTF-8: то ли один байт, то ли два :( * Однобайтные кодировки: без указания кодировки нельзя понять, что написано {{{#!highlight pycon >>> txt = "Вопрос" >>> print(*map(hex, map(ord, txt))) 0x412 0x43e 0x43f 0x440 0x43e 0x441 >>> txt.encode() b'\xd0\x92\xd0\xbe\xd0\xbf\xd1\x80\xd0\xbe\xd1\x81' >>> sys.getdefaultencoding() 'utf-8' >>> txt.encode('utf-8') b'\xd0\x92\xd0\xbe\xd0\xbf\xd1\x80\xd0\xbe\xd1\x81' >>> txt.encode('WINDOWS-1251') b'\xc2\xee\xef\xf0\xee\xf1' >>> txt.encode('KOI8-R') b'\xf7\xcf\xd0\xd2\xcf\xd3' >>> txt.encode('WINDOWS-1251').decode('KOI8-R') 'бНОПНЯ' }}} * Представление строк внутри Python: т. н. «питоний unicode» (двухбайтовый) * Если в строке нет ни одного не-ASCII символа, она хранится побайтово, но это абсолютно прозрачно, кроме размера: {{{#!highlight pycon >>> sys.getsizeof("qwe") 52 >>> sys.getsizeof("qwer") 53 >>> sys.getsizeof("qwert") 54 >>> sys.getsizeof("qwertЫ") 86 >>> sys.getsizeof("qwertЫs") 88 >>> sys.getsizeof("qwertЫsf") }}} |
|
Строка 44: | Строка 84: |
* '''TODO''' | |
Строка 50: | Строка 90: |
{{{#!highlight pycon >>> import pickle >>> pickle.dumps(0x14131211) b'\x80\x04\x95\x06\x00\x00\x00\x00\x00\x00\x00J\x11\x12\x13\x14.' >>> pickle.dumps(0x14131211)[-5:] b'\x11\x12\x13\x14.' >>> du = pickle.dumps(123.123e20) >>> du b'\x80\x04\x95\n\x00\x00\x00\x00\x00\x00\x00GD\x84\xdb\x9b\xe5\x05\x1cP.' >>> ud = pickle.loads(du) >>> ud 1.23123e+22 >>> F = open("serialized", "bw") >>> pickle.dump(100500, F) >>> pickle.dump([1, "WER", None], F) >>> pickle.dump(b"QWWER", F) >>> F.close() >>> F = open("serialized", "br") >>> pickle.load(F) 100500 >>> pickle.load(F) [1, 'WER', None] >>> pickle.load(F) b'QWWER' >>> class C: ... A = 3 ... >>> c = C() >>> du = pickle.dumps(c) >>> ud = pickle.loads(du) >>> ud <__main__.C object at 0x7f0e60c502b0> >>> ud.A 3 >>> ud = pickle.loads(du) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: Can't get attribute 'C' on <module '__main__' (<_frozen_importlib_external.SourceFileLoader object at 0x7f0e60c8bac0>)> >>> class C: ... E = 100500 ... >>> ud = pickle.loads(du) >>> ud <__main__.C object at 0x7f0e60b50b20> >>> ud.A Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'C' object has no attribute 'A' >>> ud.E 100500 }}} |
|
Строка 54: | Строка 145: |
* пример: заголовок PNG | |
Строка 56: | Строка 146: |
* <!> последовательность байтов? | * последовательность байтов * Пример: [[WP:Portable_Network_Graphics#File_format|заголовок PNG]] {{{#!python import struct import zlib import sys HEADER = "8B" CHUNK = "!I4s" CRC = "!I" IHDR = "!IIBBBBB" def readpack(fmt, fle): return struct.unpack(fmt, fle.read(struct.calcsize(fmt))) payload = b'' with open(sys.argv[1], "br") as f: png = readpack(HEADER, f) print(*map(hex, png)) while (chunk := readpack(CHUNK, f))[1] != b"IEND": print(*chunk) data = f.read(chunk[0]) crc = readpack(CRC, f) if chunk[1] == b"IHDR": w, h, bpp, col, comp, filt, i = struct.unpack(IHDR, data) print(f"{w}×{h}, {bpp=}, {col=}, {comp=}, {filt=}, {i=}") elif chunk[1] == b"IDAT": payload += data print(len(payload), w, h, w*h) payload = zlib.decompress(payload) print(len(payload), w, h, w*h) }}} |
Строка 60: | Строка 182: |
{{{#!highlight pycon >>> import dbm >>> F = dbm.open("data.db", "c") >>> F["qwe"] = "rty" >>> F["asd"] = "zxcv" >>> F["qerw"] = "werw" >>> F["123"] = "123" >>> >>> F["asd"] b'zxcv' >>> F[b"asd"] b'zxcv' >>> F["Ы"] = "Ы" >>> F["Ы"] b'\xd0\xab' >>> F.close() >>> F = dbm.open("data.db", "r") >>> F["qerw"] b'werw' >>> k = F.firstkey() >>> k b'\xd0\xab' >>> while k: ... print(F[k]) ... k = F.nextkey(k) ... b'\xd0\xab' b'rty' b'zxcv' b'werw' b'123' }}} |
Работа с файлами
(Долг за прошлую лекцию — дескрипторы)
Оператор with
Заранее задать finally (например, закрыть открытый файл, даже если были исключения)
протокол контекстного менеждера
.__enter__() / .__exit__(exc_type, exc_val, exc_tb)
Например, with open("file") as f: …
Или (сначала сделать простой вариант, без __init__ и raise)
Далее см. contextlib.html
Просто файлы
open(), r/w/a и т. п.
.read()/.write()/.readline()
файл как итератор, .readlines()
.seek(),.tell()
- текстовые и двоичные
повтор: str, bytes и bytearray
b/t
файл и with, зачем нужно
бНОПНЯ
- Понятие кодировки. Unicode, UTF* и прочее
Кодировка: соответствие некоторого числа конкретному символу (например, описанному в Unicode)
- Тысячи их
UTF-8: то ли один байт, то ли два
- Однобайтные кодировки: без указания кодировки нельзя понять, что написано
1 >>> txt = "Вопрос" 2 >>> print(*map(hex, map(ord, txt))) 3 0x412 0x43e 0x43f 0x440 0x43e 0x441 4 >>> txt.encode() 5 b'\xd0\x92\xd0\xbe\xd0\xbf\xd1\x80\xd0\xbe\xd1\x81' 6 >>> sys.getdefaultencoding() 7 'utf-8' 8 >>> txt.encode('utf-8') 9 b'\xd0\x92\xd0\xbe\xd0\xbf\xd1\x80\xd0\xbe\xd1\x81' 10 >>> txt.encode('WINDOWS-1251') 11 b'\xc2\xee\xef\xf0\xee\xf1' 12 >>> txt.encode('KOI8-R') 13 b'\xf7\xcf\xd0\xd2\xcf\xd3' 14 >>> txt.encode('WINDOWS-1251').decode('KOI8-R') 15 'бНОПНЯ' 16
- Представление строк внутри Python: т. н. «питоний unicode» (двухбайтовый)
- Если в строке нет ни одного не-ASCII символа, она хранится побайтово, но это абсолютно прозрачно, кроме размера:
Типизированные файлы
- объекты: чтение и запись объектов Python
pickle.dumps(obj) / pickle.dump(obj, file)
pickle.loads(bytes_object) / pickle.load(file)
1 >>> import pickle 2 >>> pickle.dumps(0x14131211) 3 b'\x80\x04\x95\x06\x00\x00\x00\x00\x00\x00\x00J\x11\x12\x13\x14.' 4 >>> pickle.dumps(0x14131211)[-5:] 5 b'\x11\x12\x13\x14.' 6 >>> du = pickle.dumps(123.123e20) 7 >>> du 8 b'\x80\x04\x95\n\x00\x00\x00\x00\x00\x00\x00GD\x84\xdb\x9b\xe5\x05\x1cP.' 9 >>> ud = pickle.loads(du) 10 >>> ud 11 1.23123e+22 12 >>> F = open("serialized", "bw") 13 >>> pickle.dump(100500, F) 14 >>> pickle.dump([1, "WER", None], F) 15 >>> pickle.dump(b"QWWER", F) 16 >>> F.close() 17 >>> F = open("serialized", "br") 18 >>> pickle.load(F) 19 100500 20 >>> pickle.load(F) 21 [1, 'WER', None] 22 >>> pickle.load(F) 23 b'QWWER' 24 >>> class C: 25 ... A = 3 26 ... 27 >>> c = C() 28 >>> du = pickle.dumps(c) 29 >>> ud = pickle.loads(du) 30 >>> ud 31 <__main__.C object at 0x7f0e60c502b0> 32 >>> ud.A 33 3 34 >>> ud = pickle.loads(du) 35 Traceback (most recent call last): 36 File "<stdin>", line 1, in <module> 37 AttributeError: Can't get attribute 'C' on <module '__main__' (<_frozen_importlib_external.SourceFileLoader object at 0x7f0e60c8bac0>)> 38 >>> class C: 39 ... E = 100500 40 ... 41 >>> ud = pickle.loads(du) 42 >>> ud 43 <__main__.C object at 0x7f0e60b50b20> 44 >>> ud.A 45 Traceback (most recent call last): 46 File "<stdin>", line 1, in <module> 47 AttributeError: 'C' object has no attribute 'A' 48 >>> ud.E 49 100500 50
небезопасно
- структуры типа Си:
- последовательность байтов
Пример: заголовок PNG
1 import struct 2 import zlib 3 import sys 4 5 HEADER = "8B" 6 CHUNK = "!I4s" 7 CRC = "!I" 8 IHDR = "!IIBBBBB" 9 10 def readpack(fmt, fle): 11 return struct.unpack(fmt, fle.read(struct.calcsize(fmt))) 12 13 payload = b'' 14 with open(sys.argv[1], "br") as f: 15 png = readpack(HEADER, f) 16 print(*map(hex, png)) 17 while (chunk := readpack(CHUNK, f))[1] != b"IEND": 18 print(*chunk) 19 data = f.read(chunk[0]) 20 crc = readpack(CRC, f) 21 if chunk[1] == b"IHDR": 22 w, h, bpp, col, comp, filt, i = struct.unpack(IHDR, data) 23 print(f"{w}×{h}, {bpp=}, {col=}, {comp=}, {filt=}, {i=}") 24 elif chunk[1] == b"IDAT": 25 payload += data 26 27 print(len(payload), w, h, w*h) 28 payload = zlib.decompress(payload) 29 print(len(payload), w, h, w*h)
- базы данных
- Идея: интерфейс словаря (ключ:значение) + быстрый поиск под капотом
1 >>> import dbm 2 >>> F = dbm.open("data.db", "c") 3 >>> F["qwe"] = "rty" 4 >>> F["asd"] = "zxcv" 5 >>> F["qerw"] = "werw" 6 >>> F["123"] = "123" 7 >>> 8 >>> F["asd"] 9 b'zxcv' 10 >>> F[b"asd"] 11 b'zxcv' 12 >>> F["Ы"] = "Ы" 13 >>> F["Ы"] 14 b'\xd0\xab' 15 >>> F.close() 16 >>> F = dbm.open("data.db", "r") 17 >>> F["qerw"] 18 b'werw' 19 >>> k = F.firstkey() 20 >>> k 21 b'\xd0\xab' 22 >>> while k: 23 ... print(F[k]) 24 ... k = F.nextkey(k) 25 ... 26 b'\xd0\xab' 27 b'rty' 28 b'zxcv' 29 b'werw' 30 b'123' 31
- Файлы с известной структурой
- Тысячи их, часть поддерживают файловый протокол, часть — нет
Д/З
TODO