2025-09-10:仓库迁移

This commit is contained in:
2025-09-10 16:12:45 +08:00
parent e0e49b0ac9
commit 3130e336a1
146 changed files with 4066 additions and 0 deletions

View File

@@ -0,0 +1 @@
Hello Python File

View File

@@ -0,0 +1,47 @@
if __name__ == "__main__":
path = "5.文件与IO/1.somefile.txt"
# 如果想要读取文件那open函数是唯一的选择它有很多模式
# # 只读组, 一般用于配置信息
# open(path, 'rb')
# open(path, 'rt')
#
# # 只写覆盖模式,将指针指向文件头,一般用于文件输出或覆盖旧内容
# open(path, 'wb')
# open(path, 'wt')
#
# # 只写追加模式,将指针从默认的文件头指向文件尾
# open(path, 'ab')
# open(path, 'at')
# 如果上面的任何一种模式后面有+,那么将会变成读写模式
# 在打开文件时可以指定文件的编码格式默认编码模式可以使用sys库进行查询
import sys
print(sys.getdefaultencoding())
# 当我们想打开文件的时候不建议直接使用上面的open函数因为这样需要每次记住手动关闭打开的文件像这样
# 当然二进制写入不需要指定encoding 正常来说需要指定encoding='utf-8'
a = open(path, 'wb')
a.write(b'Hello Python File\n')
a.close()
# 我们可以使用with语句来为文件创建一个上下文环境在程序离开with的程序段以后会自动关闭文件
with open(path, 'rb') as f:
# 记住如果是二进制写入解出来的时候要用utf-8解码一下
print(f.read())
# 可以看到文件已经被关闭了
print(f.closed)
# 在UNIX和Windows上换行符不太相同UNIX是\n而windows是\r\n
# Python在读取文件时做了内置的转换统一换行符为\n,如果不需要这种转换可以设置newline=''
open(path, 'rb', newline='')
# 如果遇见解码错误只需要更换encoding就行, 也可以设置错误解决方案字段errors
open(path, 'rb', encoding='utf-8', errors='replace')

BIN
5.文件与IO/10.data Normal file

Binary file not shown.

View File

@@ -0,0 +1,44 @@
import os
import mmap
if __name__ == '__main__':
def memory_map(file_path, access=mmap.ACCESS_WRITE):
size = os.path.getsize(file_path)
fild_data = os.open(file_path, os.O_RDWR)
return mmap.mmap(fild_data, size, access=access)
SIZE = 1000000
# with open(r'5.文件与IO/10.data', 'wb') as f:
# f.seek(SIZE - 1)
# f.write(b'\x00')
m = memory_map('5.文件与IO/10.data')
print(len(m))
m[0:11] = b'Hello World'
m.close()
with open(r'5.文件与IO/10.data', 'rb') as f:
print(f.read(11))
# 当然这个函数得益于他的open内嵌也能在with的上下文中打开并自动关闭
with memory_map('5.文件与IO/10.data') as m:
print(len(m))
print(m.closed)
# 当然如果你想只读可以在access里设置成mmp.ACCESS_READ,
# 如果只想把文件拷贝到内存而不是直接在文件里修改mmp.ACCESS_COPY非常有用
# mmap和memoryview又有所不同
m = memory_map('5.文件与IO/10.data')
v = memoryview(m).cast('I')
v[0] = 7
m[0:4] = b'\x07\x01\x00\x00'
print(m[0:4])
print(v[0])
# 可以看出来memoryview在做转换的时候用的是小端存储
print(int.from_bytes(m[0:4], byteorder='little'))
print(int.from_bytes(m[0:4], byteorder='big'))
v.release()
m.close()

View File

@@ -0,0 +1,20 @@
import os
if __name__ == '__main__':
path = '/Users/beazley/Data/data.csv'
# 如果我们想要得到地址的最后一部分可以使用basename字段
print(os.path.basename(path))
# 前面的部分作为文件夹可以使用dirname读出来
print(os.path.dirname(path))
# 如果想要拼接多个路径则可以使用join
print(os.path.join('suka', 'blyet', os.path.basename(path)))
# 想要提取出文件名可以使用splitext
print(os.path.splitext(os.path.basename(path)))
# 也可以使用expanduser展开上级目录,默认接控制台下的路径
path = "~\practice"
print(os.path.expanduser(path))

View File

@@ -0,0 +1,22 @@
import os
if __name__ == '__main__':
# 如果想知道文件是否存在可以使用os.path.exists
# 这个函数返回一个布尔值如果存在就返回T否则返回F
print(os.path.exists("file_not_exists.txt"))
print(os.path.exists("5.文件与IO/1.somefile.txt"))
# 判断是不是一个文件可以使用isfile方法
print(os.path.isfile("5.文件与IO/1.somefile.txt"))
# 判断是不是一个文件夹可以使用isdir方法
print(os.path.isdir("5.文件与IO"))
# 判断是不是一个软连接可以使用islink方法
print(os.path.isdir("5.文件与IO"))
# 想要知道islink的快捷方式指向的地址可以使用realpath方法
print(os.path.realpath("5.文件与IO"))
# os.path模块可以解决大部分路径问题包括切片、判断、拼接等唯一注意的就是记得给python程序访问路径的权限
# 如果要得到大小和修改日期,也有如下解决方案:
os.path.getsize("5.文件与IO/1.somefile.txt")
os.path.getmtime("5.文件与IO/1.somefile.txt")

View File

@@ -0,0 +1,9 @@
from os import listdir
if __name__ == '__main__':
# 如果想要得到路径下所有文件的列表那么我们可以使用listdir方法
print(listdir("5.文件与IO"))
# listdir函数返回一个文件列表
print(type(listdir()))

View File

@@ -0,0 +1,9 @@
import sys
if __name__ == "__main__":
# 默认情况下,文件名是根据系统编码来进行编码的
print(sys.getdefaultencoding())
# 如果你想要无视这种编码规则,可以使用字节串来指定文件名
with open(b'test.txt', 'w') as f:
print(f.read())

View File

@@ -0,0 +1,14 @@
if __name__ == "__main__":
# 有时候,可能会出现一些标准情况下打印会出现问题的文件名,他们不遵循系统的默认编码方式
# 这时候如果print这些文件名那么py会因为无法解码而将字符映射到一个代理编码表显然print无法处理这些代理为空的新建编码
# 解决的方案是建一个转换函数
def bad_filename(filename):
return repr(filename)[1: -1]
name = ''
try:
print(name)
except UnicodeEncodeError:
print(bad_filename(name))

View File

@@ -0,0 +1,40 @@
import urllib.request
import io
import gzip
import requests
if __name__ == "__main__":
req = urllib.request.Request('http://www.python.org/')
# 网页返回有时候会被压缩,用这句话让服务器帮我们解压完发过来,别给.gz
req.add_header('Accept-Encoding', 'gzip,deflate')
req.AutomaticDecompression='DecompressionMethods.GZip'
u = urllib.request.urlopen(req)
# 如果想将u以utf-8的方式添加编码可以使用io.TextIOWrapper对它进行封装
text = io.TextIOWrapper(u, encoding='utf-8')
print(text.read(10))
# 如果文件已经以文本形式打开,想要更换编码层,可以先将原有的编码层移除并替换
text = io.TextIOWrapper(text.detach(), encoding='latin-1')
print(text.read(10))
# Python打开文件时将文件分为三层源文件、源文件的二进制缓存buffer和解码器
f = open("5.文件与IO/1.somefile.txt", 'rt')
# 解码器层
print(f)
# 二进制缓存
print(f.buffer)
# 源文件
print(f.buffer.raw)
f.close()
# 如果想要改变decoder最好的办法就是使用detach()函数返回上一层的buffer然后再用io.TextIOWraper封装
f = open("5.文件与IO/1.somefile.txt", 'rt')
print(f)
b = f.detach()
print(b)
# 返回buffer层后再对buffer重编码
new = io.TextIOWrapper(b, encoding='latin-1', errors='xmlcharrefreplace')
print(new)

1
5.文件与IO/17.try.txt Normal file
View File

@@ -0,0 +1 @@
cakae

View File

@@ -0,0 +1,12 @@
import io
if __name__ == "__main__":
file = "5.文件与IO/17.try.txt"
# 上一章我们知道了文件打开后都长什么样子想要往文件里写字节数据怎么办直接往buffer里怼就完了、
# 这样可以绕过文件的编码层
f = open(file, "w")
f.buffer.write(b"write")
f.close()

View File

@@ -0,0 +1,10 @@
import os
if __name__ == "__main__":
# open函数除了可以对文件对象进行操作以外也可以打开一些由系统创建的文件描述符
fd = os.open("5.文件与IO/17.try.txt", os.O_WRONLY | os.O_CREAT)
# 当文件被关闭时,这些由系统创建的IO管道也会随之关闭
f = open(fd, 'wt')
f.write("ca")
f.close()

View File

@@ -0,0 +1,27 @@
from tempfile import TemporaryFile, NamedTemporaryFile, TemporaryDirectory
from bottle import delete
if __name__ == '__main__':
with TemporaryFile('w+t') as f:
f.write("hello")
f.write("temp_file")
f.seek(0)
data = f.read()
print(data)
print(f.closed)
# 如果想要对临时文件命名,使用NamedTemporaryFile,如果不想文件或文件夹在关闭后自动删除,请使用delete=False
# 跑完记得手动干掉它
with NamedTemporaryFile('w+t', delete=False) as f:
print("file name is : " + f.name)
# 你甚至可以创建一个临时文件夹
with TemporaryDirectory() as d:
print(d)
# 对临时文件,可以指定前缀后缀和文件夹,记住,文件夹一定要真的存在
with NamedTemporaryFile(prefix="PPP", suffix=".txt", dir=d) as f:
print("file name is : " + f.name)

View File

@@ -0,0 +1 @@
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

View File

@@ -0,0 +1,10 @@
if __name__ == "__main__":
# 如果想要将东西输出到文件中可以在print函数中指定file字段
# print函数的默认结尾是\n如果想要替换这个默认结尾可以在end字段设置
path = r"5.文件与IO/2.somefile.txt"
with open(path, "at") as f:
for i in range(10):
print(i, file=f, end=' ')
print("Done")

View File

@@ -0,0 +1 @@
# 这部分是硬件通信相关内容,先不学

BIN
5.文件与IO/21.test.bin Normal file

Binary file not shown.

View File

@@ -0,0 +1,23 @@
import pickle
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
if __name__ == '__main__':
# 对于一般的程序来说,可以使用pickle作为对象的序列化器
a = Person('a', 20)
file = open("5.文件与IO/21.test.bin", 'wb')
# 将序列化对象a写入file
pickle.dump(a, file)
file.close()
file = open("5.文件与IO/21.test.bin", 'rb')
# 从file读出序列化对象进行反序列化
a = pickle.load(file)
print(a.name, a.age)
# 值得一提的是,正在运行的线程被pickle打断后,会保存当前的状态,
# 当线程再次从文件中被读取,会继续之前的进度

View File

@@ -0,0 +1,8 @@
if __name__ == "__main__":
# 这是普通的打印
print(1,2,3)
# 想要使用分隔符来隔开数字可以在sep字段设置分隔符
print(1,2,3, sep="..")

Binary file not shown.

View File

@@ -0,0 +1,43 @@
from base64 import decode
def write_bin_file(bin_path):
with open(bin_path, 'wb') as f:
f.write(b'Hello BinFile')
if __name__ == "__main__":
path = "5.文件与IO/4.bin_file.bin"
write_bin_file(path)
# 如果想要打开二进制文件,那就需要做'rb'模式
with open(path, 'rb') as f:
print(f.read())
# 在打印的时候也有差异要记得先utf-8转码不然出来的是ascii
a = b'Hello BinFile'
for i in a:
print(i, end=' ')
print()
for i in a.decode('utf-8'):
print(i, end='')
print()
# C语言结构体和数组这种自带缓冲区接口的东西可以直接读写文件而不用先用encoder编码
import array
a = array.array('i', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
# 往文件里写array
with open(path, 'wb') as f:
f.write(a)
# 直接把bin array从文件里薅出来塞到b的缓冲区
b = array.array('i', [0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
with open(path, 'rb') as f:
f.readinto(b)
print(b)
# 但是这么干有风险,要谨慎应对

View File

@@ -0,0 +1 @@
missing file

View File

@@ -0,0 +1,17 @@
if __name__ == "__main__":
# 如果想要将数据写入一个已经不在文件系统中的文件可以使用open函数的x模式
try:
path = "5.文件与IO/4.bin_file.bin"
with open(path, 'xt') as f:
f.write("missing file")
# 可以看到,这个写入报了一个文件已存在的错误,如果我们用一个不存在的文件,那就会创建一个新文件成功写入
except FileExistsError:
path = "5.文件与IO/5.missing_file.bin"
with open(path, 'xt') as f:
f.write("missing file")
# 如果需要写入二进制文件同理使用xb就行

View File

@@ -0,0 +1,26 @@
import io
if __name__ == '__main__':
# io库里的StringIO和BytesIO提供了两个模拟文件的方法本质应该是在内存里整了块缓冲区
# StringIO提供了对字符串的虚拟IOBytesIO则对应字节串
# 这两个东西的操作和文件操作别无二致,就是不需要打开
s = io.StringIO()
b = io.BytesIO()
s.write("Hello_String_IO\n")
b.write(b'Hello BytesIO')
print("This is POWER!!!!!", file=s, end='')
print(s.getvalue())
s.seek(0)
print(s.read(4))
s.seek(0)
print(s.read())
print(b.getvalue())
b.seek(0)
print(b.read(4))
print(b.read())

View File

@@ -0,0 +1,18 @@
import gzip, bz2
if __name__ == "__main__":
# 如果想要读写.gz和.bz2后缀的压缩文件请使用上述两个包
with gzip.open("file.gz", 'rt') as f:
text = f.read()
with bz2.open("file.bz2", 'rt') as f:
text2 = f.read()
# 同样的如果写入可以使用wt和wb来进行这些包里的open函数支持和open函数相同的操作
# 如果想要增加压缩比那就需要调整compresslevel参数最高是默认9调低它以获取更高的性能
# 这些函数还支持对二进制打开的压缩文件做类似的管道操作
f = open("somefile.gz", 'rb')
with gzip.open(f, 'rt') as g:
text3 = g.read()

View File

@@ -0,0 +1,9 @@
from functools import partial
if __name__ == '__main__':
RECORD_SIZE = 32
# partial函数主要起参数固定的作用接受一个函数和一组预设参数相当于给函数设置默认参数而不用修改函数
with open('5.文件与IO/4.bin_file.bin', 'rb') as f:
records = partial(f.read, RECORD_SIZE)
for record in records():
print(record, end='')

View File

@@ -0,0 +1 @@
Hello World

View File

@@ -0,0 +1,44 @@
import os.path
import io
# 这是一个缓存区写入函数,目的是新建一个内存缓冲区,并把指定文件的内容写入
def read_info_buffer(filename):
# 建立一个字节数组缓冲区
buffer = bytearray(os.path.getsize(filename))
with open(filename, 'rb') as file:
file.readinto(buffer)
return buffer
if __name__ == '__main__':
# with open('5.文件与IO/9.bin_file.bin', 'wb') as f:
# f.write(b'Hello World')
# 将文件内容写入缓冲区
buf = read_info_buffer('5.文件与IO/9.bin_file.bin')
print(buf)
# 当然,缓冲区也可以有其他操作,比如切片
buf[0: 5] = b'hello'
print(buf)
# 当我们访问一个大文件时如果里面分为2个字节的多块就可以这样干
record_size = 2
buf2 = bytearray(record_size)
with open('5.文件与IO/9.bin_file.bin', 'rb') as f:
while True:
n = f.readinto(buf2)
print(buf2)
if n < record_size:
break
# 还有一个好玩的东西内存映像memoryview它允许我们直接操作对象的内存
suka = bytearray(b'suka blyet')
# 获取suka的内存地址
m = memoryview(suka)
# 将suka12~4位的地址给m2
m2 = m[1:4]
print(suka)
# 对这些地址上的数据进行相应长度的修改
m2[:] = b'abc'
# 可以看到这时候suka已经发生了变化
print(suka)