Python学习(十)IO编程(文件读写、StringIO和BytesIO、操作文件和目录、序列化)

news2025/5/19 1:12:46

目录

      • 一、什么是IO编程?
      • 二、文件读写
        • 1)读文件
        • 2)file-like Object
        • 3)二进制文件
        • 4)字符编码
        • 5)写文件
      • 三、StringIO 和 BytesIO
        • 1)StringIO
        • 2)BytesIO
      • 四、操作文件和目录
        • 1)操作文件和目录介绍
        • 2)环境变量
        • 3)操作文件和目录
      • 五、序列化
        • 1)序列化介绍
        • 2)JSON
        • 3)JSON进阶

一、什么是IO编程?

IO 在计算机中指 Input/Output,也就是 输入输出。由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。

  • 比如你打开浏览器,访问新浪首页,浏览器这个程序就需要通过网络IO获取新浪的网页。浏览器首先会发送数据给新浪服务器,告诉它我想要首页的HTML,这个动作是往外发数据,叫 Output;随后,新浪服务器把网页发过来,这个动作是从外面接收数据,叫 Input

所以,通常程序完成IO操作会有 Input 和 Output 两个数据流。当然也有只用一个的情况。比如,从磁盘读取文件到内存,就只有 Input 操作;反过来,把数据写到磁盘里,就只是一个Output操作。

IO编程中,Stream(流)是一个很重要的感念,可以把流想象成一个水管,数据就是水管内的水,但是只能单向流动。Input Stream 就是数据从外面(磁盘,网络)流进内存,Output Stream 就是数据从内存流到外面去。对于浏览网页来说,浏览器和新浪服务器之间至少需要建立两根水管,才可以既能发数据,又能收数据。

由于 CPU 和内存的速度远远高于外设的速度,所以,在IO编程中,就存在速度严重不匹配的问题。举个例子来说,比如要把 100M 的数据写入磁盘,CPU 输出 100M 的数据只需要 0.01秒,可是磁盘要接收这 100M 数据可能需要 10秒,怎么办呢?有两种办法:

  • 第一种是 CPU等待,也就是程序暂停执行后续代码,等 100M 的数据在 10秒后写入磁盘,再接着往下执行,这种模式称为 同步IO
  • 另一种办法是 CPU不等待,相当于告诉磁盘,“您老慢慢写,不着急,我接着干别的事去了”。于是,后续代码可以立刻接着执行,这种模式称为 异步IO

同步和异步的区别就在于是否等待IO执行的结果。举个例子:好比你去麦当劳点餐。

  • 同步: 你说 “来个汉堡”,服务员告诉你,对不起,汉堡需要现做,需要等5分钟,于是你站在收银台前面等了5分钟,拿到汉堡再去逛商场。
  • 异步: 你说 “来个汉堡”,服务员告诉你,对不起,汉堡需要等5分钟,您可以先去逛商场,等做好了,我们再通知您。这样你可以立刻去干别的事情(逛商场),这就是异步IO。

很明显,使用异步IO来编写程序性能会远远高于同步IO,但是异步IO的缺点是编程模型复杂。想想看,你得知道什么时候通知你 “汉堡做好了”,而通知你的方式也各不相同。如果是服务员跑过来找到你,这是 回调模式;如果服务员发短信通知你,你就得不停地检查手机,这是 轮询模式。总之,异步IO的复杂度远远高于同步IO。

操作IO的能力都是由操作系统提供的,每一种编程语言都会把操作系统提供的 低级C接口 封装起来方便使用。Python 也不例外,我们后面会详细讨论 Python 的 IO 编程接口。

注意:本章的 IO 编程都是同步模式,异步 IO 由于复杂度太高,后续涉及到服务器端程序开发时我们再讨论。

二、文件读写

读写文件是最常见的 IO操作。Python 内置了读写文件的函数,用法和C是兼容的。

读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘。所以,写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。

1)读文件

要以读文件的模式打开一个文件对象,使用 Python 内置的 open() 函数,传入文件名和标识符。如下所示:

>>> f = open('/Users/michael/test.txt', 'r')

标识符 'r' 表示 。这样,我们就成功地打开了一个文件。

如果文件不存在,open() 函数就会抛出一个 IOError 的错误,并给出错误码和详细的信息告诉你文件不存在,如下所示:

>>> f = open('notfound.txt', 'r')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'notfound.txt'

如果文件打开成功,接下来调用 read() 方法可以一次读取文件的全部内容,Python 把内容读到内存,用一个 str 对象标识。如下所示:

>>> f = open('hello.py', 'r')
>>> f.read()
"class Hello(object):\n    def hello(self, name='world'):\n        print('Hello, %s.' % name)\n"

最后一个是调用 close() 方法关闭文件。文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的。

>>> f.close()

由于文件读写时都有可能产生 IOError,一旦出错,后面的 f.close() 就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用 try ... finally 来实现:

try:
	f = open('/path/to/file', 'r')
    print(f.read())
finally:
    if f:
        f.close()

但是每次都这么写实在太繁琐,所以,Python 引入了 with 语句来自动帮我们调用 close() 方法。如下所示:

with open('/path/to/file', 'r') as f:
    print(f.read())

这和前面的 try ... finally 是一样的,但是代码更加简洁,并且不必调用 f.close() 方法。

调用 read() 会一次性读取文件的全部内容,如果文件有10G,内存就爆了,所以保险起见,可以反复调用 read(size) 方法,每次最多读取 size 个字节的内容。另外,调用 readline() 可以每次读取一行内容,调用 readlinse() 一次读取所有内容并按行返回 list。因此,要根据需要决定怎么调用:

  • 如果文件很小,read() 一次性读取最方便;
  • 如果不能确定文件大小,反复调用 read(size) 比较保险;
  • 如果是配置文件,调用 readlines() 最方便:
for line in f.readlines():
    print(line.strip()) # 把末尾的'\n'删掉
2)file-like Object

open() 函数返回的这种有个 read() 方法的对象,在 Python 中统称为 file-like Object。除了 file 外,还可以是内存的字节流,网络流,自定义流等等。file-like Object 不要求从特定类继承,只要写个 read() 方法就行。

StringIO 就是在内存中创建的 file-like Object,常用作临时缓冲。

3)二进制文件

前面讲的默认都是读取文本文件,并且是 UTF-8 编码的文本文件。要读取二级制文件,比如图片、视频等等,用 'rb' 模式打开文件即可:

>>> f = open('/Users/michael/test.jpg', 'rb')
>>> f.read()
b'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进制表示的字节
4)字符编码

要读取非 UTF-8 编码的文本文件,需要给 open() 函数传入 encoding 参数,例如:读取 GBK 编码的文件,如下所示:

>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk')
>>> f.read()
'测试'

遇到有些编码不规范的文件,你可能会遇到 UnicodeDecodeError,因为在文本文件中可能夹杂了一些非法编码的字符。遇到这种情况,open() 函数还接收一个 errors 参数,表示如果遇到编码错误后如何处理。最简单的方式是直接忽略,如下所示:

>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')
5)写文件

写文件和读文件是一样的,唯一区别是调用 open() 函数时,传入标识符 'w' 或者 'wb' 表示写文本文件或写二进制文件:

>>> f = open('test.txt', 'w')
>>> f.write('Hello, world!')
13
>>> f.close()

你可以反复调用 write() 来写入文件,但是务必要调用 f.close() 来关闭文件。

当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用 close() 方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用 close() 的后果是数据可能只写了一部分到磁盘,剩下的丢失了。所以,还是用 with 语句更保险一些,如下所示:

with open('test.txt', 'w') as f:
    f.write('Hello, world!')

要写入特定编码的文本文件,请给 open() 函数传入 encoding 参数,将字符串自动转换成指定编码。

细心的小伙伴会发现,以 'w' 模式写入文件时,如果文件已存在,会直接覆盖(相当于删除后新写入一个文件)。如果我们希望追加到文件末尾怎么办?可以传入 'a' 以追加(append)模式写入。

小结:

在 Python 中,文件读写是通过 open() 函数打开的文件对象完成的。使用 with 语句操作文件IO是个好习惯。

三、StringIO 和 BytesIO

1)StringIO

很多时候,数据读写不一定是文件,也可以在内存中读写。

StringIO 顾名思义就是在内存中读写字符串。要把字符串写入 StringIO,我们需要先创建一个 StringIO,然后像文件一样写入即可:

>>> from io import StringIO
>>> f = StringIO()
>>> f.write('hello')
5
>>> f.write(' ')
1
>>> f.write('world!')
6
>>> print(f.getvalue())
hello world!

getvalue() 方法用于获得写入后的字符串。

要读取 StringIO,可以用一个字符串初始化 StringIO,然后像读文件一样读取:

>>> from io import StringIO
>>> f = StringIO('Hello!\nHi!\nGoodbye!')
>>> while True:
...  s = f.readline()
...  if s == '':
...   break
...  print(s.strip())
...
Hello!
Hi!
Goodbye!
2)BytesIO

StringIO 操作的只能是字符串,如果要操作二进制数据,就需要使用 BytesIO

BytesIO 实现了在内存中读写字节数组,我们创建了一个 BytesIO,然后写入一些字节,如下所示:

>>> from io import BytesIO
>>> f = BytesIO()
>>> f.write('中文'.encode('utf-8'))
6
>>> print(f.getvalue())
b'\xe4\xb8\xad\xe6\x96\x87'
  • 请注意,写入的不是字符串,而是经过 UTF-8 编码的字节数组。

SpringIO 类似,可以用一个字节数组初始化 BytesIO,然后像读文件一样读取,如下所示:

>>> from io import BytesIO
>>> f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
>>> f.read()
b'\xe4\xb8\xad\xe6\x96\x87'

小结:

StringIOBytesIO 是在内存中操作 strbytes 的方法,使得和读写文件具有一样的接口。

四、操作文件和目录

1)操作文件和目录介绍

如果我们要操作文件、目录,可以在命令行下面输入操作系统提供的各种命令来完成。比如 dircp 等命令。

如果要在 Python 程序中执行这些目录和文件的操作怎么办?

其实操作系统提供的命令只是简单地调用了操作系统提供的接口函数,Python 内置的 os 模块也可以直接调用操作系统提供的接口函数。

打开 Python 交互式命令行,我们来看看如何使用 os 模块的基本功能:

>>> import os
>>> os.name # 操作系统类型
'nt'
  • 如果是 posix,说明系统是 Linux、Unix 或 Mac OS X;
  • 如果是 nt 就是 Windows 系统。

要获取详细的系统信息,可以调用 uname() 函数,如下所示:

# Windows系统
>>> os.unmae()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'os' has no attribute 'unmae'

# Linux系统
>>> os.uname()
posix.uname_result(sysname='Darwin', nodename='MichaelMacPro.local', release='14.3.0', version='Darwin Kernel Version 14.3.0: Mon Mar 23 11:59:05 PDT 2015; root:xnu-2782.20.48~5/RELEASE_X86_64', machine='x86_64')
  • 注意,uname() 函数在 Windows 上不提供,也就是说,os 模块的默写函数是跟操作系统相关的。
2)环境变量

在操作系统中定义的环境变量,全部保存在 os.environ 这个变量中,可以直接查看,如下所示:

>>> os.environ
environ({'VERSIONER_PYTHON_PREFER_32_BIT': 'no', 'TERM_PROGRAM_VERSION': '326', 'LOGNAME': 'michael', 'USER': 'michael', 'PATH': '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin:/usr/local/mysql/bin', ...})

要获取某个环境变量的值,可以调用 os.environ.get('key'),如下所示:

>>> os.environ.get('PATH')
'/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin:/usr/local/mysql/bin'
>>> os.environ.get('x', 'default')
'default'
3)操作文件和目录

操作文件和目录的函数一部分放在 os 模块中,一部分放在 os.path 模块中,这一点要注意一下。查看、创建和删除目录可以这么调用,如下所示:

# 查看当前目录的绝对路径:
>>> os.path.abspath('.')
'/Users/michael'
# 在某个目录下创建一个新目录,首先把新目录的完整路径表示出来:
>>> os.path.join('/Users/michael', 'testdir')
'/Users/michael/testdir'
# 然后创建一个目录:
>>> os.mkdir('/Users/michael/testdir')
# 删掉一个目录:
>>> os.rmdir('/Users/michael/testdir')

把两个路径合成一个时,不要直接拼字符串,而要通过 os.path.join() 函数,这样可以正确处理不同操作系统的路径分隔符。在 Linux / Unix / Mac 下,os.path.join() 返回这样的字符串:

part-1/part-2

而 Windows 下会返回这样的字符串:

part-1\part-2

同样的道理,要拆分路径时,也不要直接去拆字符串,而要通过 os.path.split() 函数,这样可以把一个路径拆分为两部分,后一部分总是最后级别的目录或文件名:

>>> os.path.split('/Users/michael/testdir/file.txt')
('/Users/michael/testdir', 'file.txt')

os.path.splitext() 可以直接让你得到文件扩展名,很多时候非常方便,如下所示:

>>> os.path.splitext('/path/to/file.txt')
('/path/to/file', '.txt')

这些合并、拆分路径的函数并不要求目录和文件要真实存在,它们只对字符串进行操作。

文件的重命名、删除,可以使用下面的函数,假定当前目录下有一个 test.txt 文件:

# 对文件重命名
>>> os.rename('test.txt', 'test.py')
# 删掉文件
>>> os.remove('test.py')

注意:复制文件的函数在 os 模块中不存在!原因是复制文件并非由操作系统提供的函数调用。理论上讲,我们通过上一节的读写文件可以完成文件复制,只不过要多写很多代码。

幸运的是 shutil 模块提供了 copyfile() 的函数,你还可以在 shutil 模块中找到很多实用函数,它们可以看作是 os 模块的补充。

最后看看如何利用 Python 的特性来过滤文件。比如我们要列出当前目录下的所有目录,只需要一行代码:

# 列出所有文件 
>>> os.listdir('.')
[...]

# 列出所有目录
>>> [x for x in os.listdir('.') if os.path.isdir(x)]
['.lein', '.local', '.m2', '.npm', '.ssh', '.Trash', '.vim', 'Applications', 'Desktop', ...]

# 列出所有的.py文件
>>> [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']
['err.py', 'hello.py', 'mydict.py', 'mydict2.py', 'mydict_test.py', 'number.py']

基本只要一行代码就可以完成我们的筛选,是不是非常简洁?

小结:

Python 的 os 模块封装了操作系统的目录和文件操作,要注意这些函数有的在 os 模块中,有的在 os.path 模块中。

五、序列化

1)序列化介绍

在程序运行的过程中,所有的变量都是在内存中,比如,定义一个字典类型:

>>> d = dict(name='Bob', age=20, score=88)

可以随时修改变量,比如把 name 改为 Bill,但是一旦程序结束,变量锁占用的内存就被操作系统全部回收。如果没有把修改后的 Bill 存储到磁盘上,下次重新运行程序,变量又被初始化为 'Bob'

我们把变量从内存中变成可存储或传输的过程称之为 序列化。在 Python 中叫 pickling,在其他语言中也被称之为 serialization、marshalling、flattening 等等,都是一个意思。

序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。

反过来,把变量内容从序列化的对象重新读到内存里称之为 反序列化,即 unpickling。

Python 提供了 pickle 模块来实现序列化。

首先,我们尝试把一个对象序列化并写入文件:

>>> import pickle
>>> d = dict(name='Bob', age=20, score=88)
>>> pickle.dumps(d)
b'\x80\x04\x95$\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x04name\x94\x8c\x03Bob\x94\x8c\x03age\x94K\x14\x8c\x05score\x94KXu.'

pickle.dumps() 方法把任意对象序列化成一个 bytes,然后,就可以把这个 bytes 写入文件。或者用另一个方法 pickle.dump() 直接把对象序列化后写入一个 file-like Object 中,如下所示:

>>> with open('dump.txt', 'wb') as f:
...  pickle.dump(d, f)
...

dump.txt 的文件内容如下:

  • 看着写入的一堆乱码内容,这些都是 Python 保护的对象内部信息。

当我们要把对象从磁盘读到内存时,可以先把内容读到一个 bytes,然后用 pickle.loads() 方法反序列化出对象,也可以直接用 pickle.load() 方法从一个 file-like Object 中直接反序列化出对象。我们打开另一个 Python 命令行来反序列化刚才保存的对象:

>>> with open('dump.txt', 'rb') as f:
...  d = pickle.load(f)
...  print(d)
...
{'name': 'Bob', 'age': 20, 'score': 88}
  • 可以看到,变量的内容又回来了。

当然,这个变量和原来的变量是完全不相干的对象,它们只是内容相同而已。

Pickle 的问题和所有其他编程语言特有的序列化问题,就是 Python语言序列化后的内容只能用 Python语言进行反序列化,并且可能不同版本的 Python彼此都不兼容。因此,只能用 Pickle 保存那些不重要的数据,不能成功地反序列化也没关系。

2)JSON

如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如 XML,但更好的方法是序列化为 JSON。因为 JSON 表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON 不仅是标准格式,并且比 XML 更快,可以直接在 Web 页面中读取,非常方便。

JSON 表示的对象就是标准的 JavaScript 语言的对象,JSON 和 Python 内置的数据类型对应如下:

JSON类型Python类型
{}dict
[]list
“string”str
1234.56int 或 float
true/falseTrue/False
nullNone

Python 内置的 json 模块提供了非常完善的 Python 对象到 JSON 格式的转换。我们先看看如何把 Python 对象变成一个 JSON,如下所示:

>>> import json
>>> d = dict(name='Bob', age=20, score=99)
>>> json.dumps(d)
'{"name": "Bob", "age": 20, "score": 99}'
  • json.dumps() 方法返回一个字符串,内容就是标准的 JSON 格式。类似的,json.dump() 方法可以直接把 JSON 写入一个 file-like Object

要把 JSON 反序列化为 Python 对象,同样有两种方法:

  • loads():把 JSON 的字符串反序列化。
  • load():从 file-like Object 中读取字符串并反序列化。
>>> json_str = '{"age": 20, "score": 88, "name": "Bob"}'
>>> json.loads(json_str)
{'age': 20, 'score': 88, 'name': 'Bob'}

由于 JSON 标准规定 JSON 编码是 UTF-8,所以我们总是能正确地在 Python 的 字符串与 JSON 的字符串之间转换。

3)JSON进阶

Python 的 dict 对象可以直接序列化为 JSON 的 {}。不过很多时候,我们更喜欢用 class 表示对象,比如定义 Student 类,然后序列化:

import json

class Student(object):
    def __init__(self, name, age, score):
        self.name = name
        self.age = age
        self.score = score

>>> s = Student('Bob', 20, 88)
>>> print(json.dumps(s))

运行代码,毫不留情地得到一个 TypeError,如下所示:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\lenovo\AppData\Local\Programs\Python\Python310\lib\json\__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "C:\Users\lenovo\AppData\Local\Programs\Python\Python310\lib\json\encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Users\lenovo\AppData\Local\Programs\Python\Python310\lib\json\encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "C:\Users\lenovo\AppData\Local\Programs\Python\Python310\lib\json\encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Student is not JSON serializable
  • 错误的原因是 Student 对象不是一个可序列化为 JSON 的对象。

如果连 class 的实例对象都无法序列化为 JSON,这肯定不合理。如果我们仔细看看 dumps() 方法的参数列表可以发现,除了第一个必须的 obj 参数外,dumps() 方法还提供了一大堆的可选参数:

  • https://docs.python.org/3/library/json.html#json.dumps

在这里插入图片描述

这些可选参数就是让我们来定制 JSON 序列化。前面的代码之所以无法让 Student 类实例序列化为 JSON,是因为默认情况下,dumps() 方法不知道如何将 Student 实例变为一个 JSON 的 {} 对象。

可选参数 default 就是把任意一个对象变成一个可序列化为 JSON 的对象,我们只需要为 Student 专门写一个转换函数,再把函数传进去即可,如下所示:

def student2dict(std):
    return {
        'name': std.name,
        'age': std.age,
        'score': std.score
    }

这样,Student 实例首先被 student2dict() 函数转换成 dict 类型,然后再被顺利序列化为 JSON,如下所示:

>>> json.dumps(s, default=student2dict)
'{"name": "Bob", "age": 20, "score": 88}'

不过,下次如果遇到一个 Teacher 类的实例,照样无法序列化为 JSON。我们可以偷个懒,把任意 class 的实例变为 dict 类型:

>>> json.dumps(s, default=lambda obj: obj.__dict__)
'{"name": "Bob", "age": 20, "score": 88}'

因为通常 class 的实例都有一个 __dict__ 属性,它就是一个 dict,用来存储实例变量。也有少数例外,比如定义了 __slots__ 的 class。

同样的道理,如果我们要把 JSON 反序列化为一个 Student 对象实例,loads() 方法首先转换出一个 dict 对象,然后,我们传入的 object_hook 函数负责把 dict 转换为 Student 实例:

def dict2student(d):
    return Student(d['name'], d['age'], d['score'])

运行结果如下:

>>> json_str = '{"age": 20, "score": 88, "name": "Bob"}'
>>> json.loads(json_str, object_hook=dict2student)
<__main__.Student object at 0x000001A9742B7610>

打印出来的是反序列化的 Student 实例对象。

小结:

Python 语言特定的序列化模块是 pickle,但如果要把序列化搞得更通用、更符合 Web 标准,就可以使用 json 模块。

json 模块的 dumps()loads() 函数是定义得非常好的接口的典范。当我们使用时,只需要传入一个必须的参数。但是,当默认的序列化或反序列化机制不满足我们的要求时,我们又可以传入更多的参数来定制序列化或反序列化的规则,既做到了接口简单易用,又坐到了充分的扩展性和灵活性。

整理完毕,完结撒花~ 🌻





参考地址:

1.Python课程,https://liaoxuefeng.com/books/python/introduction/index.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2278605.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5、docker-compose和docker-harbor

安装部署docker-compose 自动编排工具&#xff0c;可以根据dockerfile自动化的部署docker容器。是yaml文件格式&#xff0c;注意缩进。 1、安装docker-compose 2、配置compose配置文件docker-compose.yml 3、运行docker-compose.yml -f&#xff1a;指定文件&#xff0c;up&…

JS宏进阶: 工厂函数与构造函数

一、构造函数 在JavaScript中&#xff0c;构造函数是一种用于创建和初始化对象的特殊函数。构造函数的名字通常以大写字母开头&#xff0c;以区分于普通函数。通过new关键字调用构造函数&#xff0c;可以创建一个新的实例对象&#xff0c;并自动执行构造函数内部的代码来初始化…

uniapp 微信小程序 editor 富文本编辑器

<view class"inp boxsizing"><view class"contentBox"><!-- 富文本编辑器 --><view classwrapper><view classtoolbar tap"format"><view :class"formats.bold ? ql-active : " class"iconfon…

Python根据图片生成学生excel成绩表

学习笔记&#xff1a; 上完整代码 import os import re from openpyxl import Workbook, load_workbook from openpyxl.drawing.image import Image as ExcelImage from PIL import Image as PilImage# 定义图片路径和Excel文件路径 image_dir ./resources/stupics # 图片所…

在VMwareFusion中使用Ubuntu

在VMwareFusion使用Ubuntu 在VMwareFusion使用Ubuntu背景在VMwareFusion虚拟机里使用Ubuntu1、集成桌面工具2、主机和虚拟机之间共享剪贴板内容3、设置root用户密码4、设置静态ip4.1、静态ip和动态ip的区别4.2、查看当前ip4.2、linux网络配置文件所在位置4.3、基于ubuntu22.04.…

农业农村大数据应用场景|珈和科技“数字乡村一张图”解决方案

近年来&#xff0c;珈和科技持续深耕农业领域&#xff0c;聚焦时空数据服务智慧农业。 珈和利用遥感大数据、云计算、移动互联网、物联网、人工智能等先进技术&#xff0c;搭建“天空地一体化”监测体系&#xff0c;并创新建设了150的全球领先算法模型&#xff0c;广泛应用于高…

python 利用 ddddocr包 ocr识别图片码

ddddocr 是一个轻量级的 OCR&#xff08;光学字符识别&#xff09;库&#xff0c;适用于识别图片中的文字&#xff0c;包括验证码等图像文本。要使用 ddddocr 进行图片验证码的识别&#xff0c;可以按照以下步骤进行&#xff1a; 1. 安装 ddddocr 包 首先&#xff0c;你需要安…

【论文阅读】基于空间相关性与Stacking集成学习的风电功率预测方法

文章目录 摘要0. 引言1. 空间相关性分析2. 风电功率预测模型2.1 Stacking 集成策略2.2 基学习器2.2.1 基于机器学习算法的基学习器2.2.2 基于神经网络的基学习器2.2.3 基于粒子群优化算法的超参数优化 2.3 元学习器2.4 基于空间相关性与Stacking集成学习的风电功率预测方法 3 算…

在.NET用C#将Word文档转换为HTML格式

将Word文档转换为HTML格式尤其具有显著的优势&#xff0c;它不仅能够确保文档内容在多种设备和平台上保持一致灵活的显示&#xff0c;还便于通过网络进行传播和集成到各种Web应用中。随着越来越多的企业和开发者寻求更灵活、更具兼容性的文件处理方式&#xff0c;.NET框架下的C…

EasyExcel的应用

一、简单使用 引入依赖&#xff1a; 这里我们可以使用最新的4.0.2版本&#xff0c;也可以选择之前的稳定版本&#xff0c;3.1.x以后的版本API大致相同&#xff0c;新的版本也会向前兼容&#xff08;3.1.x之前的版本&#xff0c;部分API可能在高版本被废弃&#xff09;&…

【git】如何删除本地分支和远程分支?

1.如何在 Git 中删除本地分支 本地分支是您本地机器上的分支&#xff0c;不会影响任何远程分支。 &#xff08;1&#xff09;在 Git 中删除本地分支 git branch -d local_branch_name git branch 是在本地删除分支的命令。-d是一个标志&#xff0c;是命令的一个选项&#x…

wps数据分析000002

目录 一、快速定位技巧 二、快速选中技巧 全选 选中部分区域 选中部分区域&#xff08;升级版&#xff09; 三、快速移动技巧 四、快速录入技巧 五、总结 一、快速定位技巧 ctrl→&#xff08;上下左右&#xff09;快速定位光标对准单元格的上下部分双击名称单元格中…

Java算法 二叉树入门 力扣简单题相同的树 翻转二叉树 判断对称二叉树 递归求二叉树的层数

目录 模版 先序遍历 中序遍历 后序遍历 力扣原题 相同的二叉树 力扣原题 翻转二叉树 遍历树的层数 题目 静态变量 核心逻辑 模版 // 二叉树public static class Node{public int value;public Node left;public Node right;public Node(int v) {valuev;}} 先序遍历 …

【Mysql进阶知识】Mysql 程序的介绍、选项在命令行配置文件的使用、选项在配置文件中的语法

目录 一、程序介绍 二、mysqld--mysql服务器介绍 三、mysql - MySQL 命令行客户端 3.1 客户端介绍 3.2 mysql 客户端选项 指定选项的方式 mysql 客户端命令常用选项 在命令行中使用选项 选项(配置)文件 使用方法 选项文件位置及加载顺序 选项文件语法 使用举例&am…

ESP32云开发二( http + led + lcd)

文章目录 前言先上效果图platformio.iniwokwi.tomldiagram.json源代码编译编译成功上传云端完结撒花⭐⭐⭐⭐⭐ 前言 阅读此篇前建议先看 此片熟悉下wokwi https://blog.csdn.net/qq_20330595/article/details/144289986 先上效果图 Column 1Column 2 platformio.ini wokwi…

医疗集群系统中基于超融合数据库架构的应用与前景探析

一、引言 1.1 研究背景与意义 随着医疗信息化的飞速发展,医疗数据呈爆炸式增长。从日常诊疗记录、患者病历,到各类医疗影像、检查检验数据等,海量信息不断涌现。据统计,医疗数据的年增长率高达 30% 以上 ,2025 年,全球医疗数据量将达到 2314 艾字节(EB)。如此庞大的数…

Flask学习入门笔记

Flask学习入门笔记 前言1. 安装Flask2. 创建一个简单的Flask应用3. 路由与视图函数3.1 基本路由3.2 动态路由3.3 HTTP方法 4. 请求与响应4.1 获取请求数据4.2 返回响应 5. 模板渲染5.1 基本模板渲染5.2 模板继承 6. 静态文件6.1 静态文件的目录结构6.2 在模板中引用静态文件6.2…

Java File、IO流、字节输入流 、字节输出流 、字符输入流 、字符输入流 、缓冲流、转换流、打印流、数据流、序列化流、IO框架

一. File File是Java.io.包下的类&#xff0c;File类的对象用于代表当前操作系统的文件/文件夹 File类只能对文件本身进行操作&#xff0c;不能读写文件里面存储的数据。 1. 创建对象 构造器说明public File(String pathname)根据文件路径创建文件对象public File(String pare…

宇泰串口卡驱动在Ubuntu22.04编译、安装汇总

从官网下载驱动官网地址 上传到Ubuntu, 目录结构如下&#xff1a; 驱动源代码: 驱动代码是基于开源项目编译来的 编译路径不能有中文路径&#xff0c;否则可能有类似错误 源码是基于Linux2.3内核编译&#xff0c;我当前是6.8.0-51&#xff0c;数据结构有升级&#xff0c;需要调…

Linux -- 初识HTTP协议

目录 什么是HTTP协议 什么是 URL &#xff1f; 理解 URL 初识HTTP 请求与响应格式 代码验证 gitee HTTP.hpp 结果 什么是HTTP协议 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;主要用于客户端&#xff08;通常是浏览器&#…