当前位置: 首页 > news >正文

Python基础

https://www.w3schools.com/https://docs.python.org/3/
Python 介绍
Python是跨平台的,它可以运行在Windows、Mac和各种Linux/Unix系统上。在Windows上写Python程序,放到Linux上也是能够运行的。
要开始学习Python编程,首先就得把Python安装到你的电脑里。安装后,你会得到Python解释器(就是负责运行Python程序的),一个命令行交互环境,还有一个简单的集成开发环境。

Python 解释器:当我们编写Python代码时,我们得到的是一个包含Python代码的以.py为扩展名的文本文件。要运行代码,就需要Python解释器去执行.py文件。
CPython:当我们从Python官方网站下载并安装好Python 3.x后,我们就直接获得了一个官方版本的解释器:CPython。这个解释器是用C语言开发的,所以叫CPython。在命令行下运行python就是启动CPython解释器。
CPython是使用最广的Python解释器。教程的所有代码也都在CPython下执行。

在Python交互式模式下,可以直接输入代码,然后执行,并立刻得到结果;在命令行模式下,可以直接运行.py文件。

安装、卸载和管理 python(macOS )
安装方式
1、 使用 homebrew 安装

安装

brew install python3

查看

brew list | grep python
2、使用 Python 版本管理工具 pyenv 安装(推荐)
pyenv 是一个 Python 版本管理工具,它允许你在同一台机器上安装和切换多个 Python 版本。
使用 pyenv 安装 python 时报错:
python-build: use zlib from xcode sdk
Traceback (most recent call last):
File “”, line 1, in
import lzma
File “/Users/xxxx/.pyenv/versions/3.13.1/lib/python3.13/lzma.py”, line 27, in
from _lzma import *
ModuleNotFoundError: No module named ‘_lzma’
WARNING: The Python lzma extension was not compiled. Missing the lzma lib?
解决办法:卸载 pyenv unistall 3.13.1、安装 lzma 开发库 brew install xz、安装 pyenv install 3.13,这次没报错啦,安装成功。
python-build: use openssl@3 from homebrew
python-build: use readline from homebrew
Downloading Python-3.13.1.tar.xz…
-> https://www.python.org/ftp/python/3.13.1/Python-3.13.1.tar.xz
Installing Python-3.13.1…
python-build: use readline from homebrew
python-build: use zlib from xcode sdk
Installed Python-3.13.1 to /Users/xxxx/.pyenv/versions/3.13.1
安装成功后配置环境变量, vim ~/.zshrc,以下是对.zshrc文件中这两行内容的详细解释:
export PATH=“HOME/.pyenv/bin:PATH”
● export:这是一个 shell 命令,用于将变量导出为环境变量,使其在当前 shell 及其子 shell 中可用。
● PATH:这是一个环境变量,存储了系统查找可执行程序的目录路径列表。当你在命令行输入一个命令时,系统会根据 PATH 中列出的目录顺序查找该命令的可执行文件。
● HOME:这是一个环境变量,代表用户的主目录,例如/Users/yourusername。
● HOME/.pyenv/bin:这是 pyenv 工具的可执行文件所在的目录路径。pyenv 是一个强大的 Python 版本管理工具,它的可执行文件通常安装在用户主目录下的 .pyenv/bin 目录中。
● PATH:代表当前的 PATH 环境变量。整体作用:这行代码将 可执行文件通常安装在用户主目录下的 .pyenv/bin 目录中。
● HOME/.pyenv/bin 目录添加到 PATH 环境变量的开头。这样做的好处是,当你在命令行输入 pyenv 命令时,系统会首先在 $HOME/.pyenv/bin 目录中查找 pyenv 的可执行文件。由于该目录被添加到 PATH 的最前面,它会优先于系统中其他可能的 pyenv 可执行文件目录,确保使用的是通过 pyenv 管理的版本,避免使用系统默认的可能冲突的工具。
eval “(pyenv init -)”
● eval:这是一个 shell 命令,用于将字符串作为 shell 命令来执行。
● pyenv init -:这是 pyenv 的一个子命令,它会输出一段 shell 脚本。
● (…):这是命令替换语法,它将 pyenv init - 命令的输出作为一个字符串。
整体作用:执行 pyenv init - 命令并将其输出作为 shell 脚本进行评估和执行。通常,该输出会修改 PATH 环境变量,将 pyenv 管理的不同 Python 版本的可执行文件添加到 PATH 中,同时还会添加一些 pyenv 所需的其他环境变量和 shell 函数,例如为 pyenv 提供自动补全功能等。这个命令对于 pyenv 的正常工作至关重要,它使得 pyenv 可以在用户的 shell 环境中正确地管理 Python 版本,包括切换版本、安装新版本、设置本地或全局版本等操作。

Python 配置

下面两条命令是在创建命令别名,将python命令只想系统默认的/usr/bin/python3

并让python3命令等同于python。这样设置后无论输入python还是python3,都会

执行系统默认的python3版本,这和pyenv冲突了

alias python=/usr/bin/python3

alias python3=python

pyenv 配置

export:这是一个 shell 命令,用于将变量导出为环境变量,使其在当前 shell 及其子 shell 中可用。

PATH:这是一个环境变量,存储了系统查找可执行程序的目录路径列表。当你在命令行输入一个命令时,系统会根据 PATH 中列出的目录顺序查找该命令的可执行文件。

HOME:这是一个环境变量,代表用户的主目录,例如/Users/yourusername。

HOME/.pyenv/bin:这是 pyenv 工具的可执行文件所在的目录路径。

pyenv 是一个强大的 Python 版本管理工具,它的可执行文件通常安装在用户主目录下的 .pyenv/bin 目录中。

export PATH=“ H O M E / . p y e n v / b i n : HOME/.pyenv/bin: HOME/.pyenv/bin:PATH”
eval “$(pyenv init -)”
● 保存后退出 vim
● 刷新一下文件信息 source ~/.zshrc
● python --version 查看是否配置成功

切换到新安装的 Python 版本

全局切换

pyenv global 3.13.1

项目切换,执行这个命令后,项目所在根目录会生成一个.python-version文件,文件内容里指示了python的版本

pyenv local 3.13.1
3、pkg 安装包安装
where python 查看 python 安装目录
配置 python 命令别名,使得可以在命令行工具中运行 python 命令。

4、 几种安装方式的区别
pkg 安装 Python 通常会将 Python 安装在系统的标准位置,而 pyenv 管理的 Python 版本通常存储在 ~/.pyenv/versions 目录下。
当你使用 pkg 安装 Python 时,pyenv 不会自动识别这些系统级安装的 Python 版本,因为它们不在 pyenv 的管理范围内。
使用 pyenv 管理 Python 版本可以让你更方便地进行 Python 开发,避免因系统级安装和 pyenv 管理的版本混淆而导致的问题。

卸载注意事项
● 确认版本:
○ 在执行卸载操作之前,确保你要卸载的 Python 版本是通过 Homebrew 安装的,并且确认该版本不再需要,因为卸载后可能会影响依赖该 Python 版本的项目。
● 相关依赖:
○ 有些软件可能依赖于 Python,卸载 Python 可能会影响这些软件的正常运行。在卸载之前,考虑是否有软件依赖于该 Python 版本。
● 备份和迁移:
○ 如果你在使用 Python 开发项目,在卸载之前,确保对重要的项目和数据进行备份,并且考虑迁移到其他 Python 版本。

管理 Python
查找 Python 安装路径
首先,你可以使用 which python 命令来查找当前 python 命令的位置,例如:
which python
这将输出 Python 可执行文件的路径,可能是 /usr/bin/python、/usr/local/bin/python 或其他位置。
确定 Python 的来源
在 macOS 中,系统自带 Python 2.x 版本,通常位于 /usr/bin/python。如果你看到的是这个位置,可能是在使用系统自带的 Python 版本。对于系统自带的 Python,不建议直接删除或卸载,因为它可能被系统的一些功能所依赖。
如果是系统自带的 Python,那么不建议卸载,因为可能会影响系统的稳定性和功能。如果你想使用不同的 Python 版本,可以使用 pyenv 或 conda 等版本管理工具,而不是卸载系统自带的 Python。
如果你使用了 pkg 或其他第三方包管理器(除了 Homebrew),可能会将 Python 安装在不同的位置,如 /usr/local/bin/python 或 /opt/local/bin/python。要查找该包管理器并卸载 Python,你需要查阅该包管理器的文档。
如果你手动安装了 Python,它可能在 /usr/local 或自定义的目录中。
基本语法
当语句以冒号:结尾时,缩进的语句视为代码块。缩进有利有弊。(1)好处是强迫你写出格式化的代码,但没有规定缩进是几个空格还是Tab。按照约定俗成的惯例,应该始终坚持使用4个空格的缩进。(2)缩进的另一个好处是强迫你写出缩进较少的代码,你会倾向于把一段很长的代码拆分成若干函数,从而得到缩进较少的代码。(3)缩进的坏处就是“复制-粘贴”功能失效了,这是最坑爹的地方。当你重构代码时,粘贴过去的代码必须重新检查缩进是否正确。此外,IDE很难像格式化Java代码那样格式化Python代码。
数据类型
Python程序是大小写敏感的。
整数:对于很大的数,例如10000000000,很难数清楚0的个数。Python允许在数字中间以_分隔,因此,写成10_000_000_000和10000000000是完全一样的。十六进制数也可以写成0xa1b2_c3d4。
字符串:如果字符串内部既包含’又包含"怎么办?可以用转义字符\来标识,比如:
‘I’m “OK”!’
布尔值:可以用and、or和not运算。and运算是与运算,只有所有都为True,and运算结果才是True。
空值:是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值。
除法:/除法计算结果是浮点数,即使是两个整数恰好整除,结果也是浮点数。还有一种除法是//,称为地板除,两个整数的除法仍然是整数。整数的地板除//永远是整数,即使除不尽。要做精确的除法,使用/就可以。
变量:Python支持多种数据类型,在计算机内部,可以把任何数据都看成一个“对象”,而变量就是在程序中用来指向这些数据对象的,对变量赋值就是把数据和变量给关联起来。
字符和编码
ASCII 编码:它是最早出现的字符编码标准,使用 7 位二进制数来表示 128 个常见的英文字母、数字、标点符号等基本字符,简单且在早期计算机处理英文信息方面应用广泛,但无法表示其他语言众多的字符。
Unicode 编码:它是为了解决不同语言字符统一编码的问题而诞生,试图给世界上所有的字符都分配一个唯一的数字编号,涵盖了几乎各种语言文字、符号等,范围非常广,保证了每个字符在全球范围内有统一的标识,不过其直接存储或传输时较占空间。
UTF-8 编码:它是 Unicode 编码的一种实现方式,属于可变长的编码格式。UTF-8 会根据字符的不同,采用不同长度的字节来进行编码存储,比如对于 ASCII 编码里原本的那些字符,用 1 个字节表示,和 ASCII 编码兼容,而对于其他复杂些的 Unicode 字符则用 2 个、3 个甚至更多字节来编码,这样既兼容了 ASCII 编码,又能有效地节省存储空间,利于在网络传输等场景下使用。

纯英文的str可以用ASCII编码为bytes,内容是一样的,含有中文的str可以用UTF-8编码为bytes。含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围,Python会报错。
由于Python源代码也是一个文本文件,所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为UTF-8编码。当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头写上这两行:
#!/usr/bin/env python3

-- coding: utf-8 --

第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。申明了UTF-8编码并不意味着你的.py文件就是UTF-8编码的,必须并且要确保文本编辑器正在使用UTF-8编码。
函数
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。
关键字参数
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
命名关键字参数
如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city和job作为关键字参数。这种方式定义的函数如下:
def person(name, age, , city, job):
print(name, age, city, job)
命名关键字参数需要一个特殊分隔符
,*后面的参数被视为命名关键字参数。
如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city和job作为关键字参数。这种方式定义的函数如下:
def person(name, age, *, city, job):
print(name, age, city, job)
命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错:

person(‘Jack’, 24, ‘Beijing’, ‘Engineer’)
Traceback (most recent call last):
File “”, line 1, in
TypeError: person() missing 2 required keyword-only arguments: ‘city’ and ‘job’
命名关键字参数可以有缺省值,从而简化调用:
def person(name, age, , city=‘Beijing’, job):
print(name, age, city, job)
使用命名关键字参数时,要特别注意,如果没有可变参数,就必须加一个
作为特殊分隔符。如果缺少*,Python解释器将无法识别位置参数和命名关键字参数
def person(name, age, city, job):

# 缺少 *,city和job被视为位置参数
pass

【综合案例】

def my_sum(a, b, c=‘c’, *d, namedKeywordParams, **kw):
print(‘必选参数’, a, b)
print(‘默认参数’, c)
print(‘可变参数’, d)
print(‘命名关键字参数’, namedKeywordParams)
print(‘关键字参数’, kw)

my_sum(1, 2, 3)

my_sum(1, 2)

my_sum(1, 2, 3, 4, 5)

my_sum(1, 2, 3, 4, 5, namedKeywordParams=‘namedKeywordParams’)
my_sum(1, 2, 3, 4, 5, namedKeywordParams=‘namedKeywordParams’, kw1=‘kw1’, kw2=‘kw2’)
高级特性
切片
练习:利用切片操作,实现一个trim()函数,去除字符串首尾的空格,注意不要调用str的strip()方法:
def trim(s):
# 判断入参是否为字符串
if not isinstance(s, str):
raise ValueError(‘入cān不是字符串’)

# 先计算字符串长度
sLength = len(s)
# 定义两个变量,分别表示空格的开始(从前往后数)和结束位置(从后往前数)
start = 0 # 指针1
end = sLength # 指针2# 如果字符串为空格组成,直接返回空字符串
if s == ' ' * sLength:return ''# 循环遍历字符串,找到第一个非空格字符的位置
for i in range(sLength):if s[i] != ' ':start = ibreak# 循环遍历字符串,找到最后一个非空格字符的位置
for i in range(sLength - 1, -1, -1):if s[i] != ' ':end = ibreak# 判断 start 和 end 的位置,如果 start 大于 end,说明字符串全是空格,返回空字符串
if start > end:return ''
else:# 返回截取后的字符串return s[start:end + 1]

测试:

if trim(‘hello ‘) != ‘hello’:
print(‘测试失败!1’)
elif trim(’ hello’) != ‘hello’:
print(‘测试失败!2’)
elif trim(’ hello ‘) != ‘hello’:
print(‘测试失败!3’)
elif trim(’ hello world ‘) != ‘hello world’:
print(‘测试失败!4’)
elif trim(’‘) != ‘’:
print(‘测试失败!5’)
elif trim(’ ') != ‘’:
print(‘测试失败!6’)
else:
print(‘测试成功!7’)
迭代
Python的for循环不仅可以用在list或tuple上,还可以作用在其他可迭代对象上。
如何判断一个对象是可迭代对象呢?方法是通过collections.abc模块的Iterable类型判断。
如果要对list实现类似Java那样的下标循环怎么办?Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身。
for index, value in enumerate([‘A’, ‘B’, ‘C’]):
print(index, value)

输出结果为

0 A

1 B

2 C

for index, value in enumerate([(1, 1), (2, 4), (3, 9)]):
print(index, value)

输出结果为

0 (1, 1)

1 (2, 4)

2 (3, 9)

练习:请使用迭代查找一个list中最小和最大值,并返回一个tuple:
def findMinAndMax(L):
if not isinstance(L, list):
raise ValueError(‘入参不是列表’)
if len(L) == 0:
return (None, None)
min = L[0]
max = L[0]
for i in L:
if i < min:
min = i
if i > max:
max = i
return (min, max)

测试

if findMinAndMax([]) != (None, None):
print(‘测试失败!’)
elif findMinAndMax([7]) != (7, 7):
print(‘测试失败!’)
elif findMinAndMax([7, 1]) != (1, 7):
print(‘测试失败!’)
elif findMinAndMax([7, 1, 3, 9, 5]) != (1, 9):
print(‘测试失败!’)
else:
print(‘测试成功!’)
列表生成式
写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来。
for循环后面还可以加上if判断。跟在for后面的if是一个筛选条件,不能带else,否则如何筛选?
还可以使用两层循环,可以生成全排列。
列表生成式也可以使用两个变量来生成list。
for前面的部分是一个表达式,它必须根据x计算出一个结果。

生成器
创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator。
如果要打印出generator的每一个元素,可以通过next()函数获得generator的下一个返回值,
创建了一个generator后,基本上永远不会调用next(),而是通过for循环来迭代它,并且不需要关心StopIteration的错误。

生成器

g = (x * x for x in range(10))

generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素

print(next(g))
print(next(g))
print(next(g))
print(next(g))

上面这种不断调用next(g)实在是太变态了,正确的方法是使用for循环,因为generator也是可迭代对象

创建了一个generator后,基本上永远不会调用next(),而是通过for循环来迭代它,并且不需要关心StopIteration的错误

for n in g:
print(n)

输出

0

1

4

9

16

25

36

49

64

81

调用 generator 函数会创建一个 generator 对象,多次调用generator函数会创建多个相互独立的 generator 。举例来说,对于下面的 fib 生成器
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1

return 'done'

如果采用如下的调用方式,那么打印的结果始终是 1。这是因为每一次调用next(fib(6)),都生成了新的 generator,那么打印出来的结果就是 fib 中第一次 yield b 的值。
print(next(fib(6)))
print(next(fib(6)))
print(next(fib(6)))

输出

1

1

1

如果是如下的调用方式,那么打印的结果是一个斐波那契数列。这是因为在每次调用next(fib)的时候执行 fib 里面的逻辑,遇到yield语句返回,再次执行时从上次返回的yield语句的暂停位置处继续执行。

fib = fib(6) # 调用generator函数会创建一个generator对象,多次调用generator函数会创建多个相互独立的generator。
print(next(fib)) # 1
print(next(fib)) # 1
print(next(fib)) # 2
print(next(fib)) # 3
print(next(fib)) # 5
如果想要拿到 generator 函数返回值’done’,必须捕获StopIteration错误,返回值包含在StopIteration的value中,例如:
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1

return 'done'

fib_6 = fib(6)
while True:
try:
print('g: ', next(fib_6))
except StopIteration as e:
print('Generator return value: ', e.value)
break
生成器更多用法请见:
https://www.doubao.com/thread/w3d2e76141bbe6751
在Python中,生成器是一种特殊的迭代器,它提供了一种更高效、更灵活的方式来处理大量数据或实现惰性计算。以下是关于Python生成器用法的详细介绍:
生成器表达式
生成器表达式是一种简洁的创建生成器的方式,它的语法类似于列表推导式,但使用圆括号而不是方括号。例如:

创建一个生成器,生成1到10的平方

generator = (i**2 for i in range(1, 11))
for num in generator:
print(num)
生成器表达式可以作为函数参数直接使用,比如计算1到100的整数和:
sum(i for i in range(1, 101))
生成器函数
生成器函数是使用yield语句而不是return语句的函数。当函数执行到yield语句时,会暂停函数的执行,并返回yield后面的值,下次调用生成器时,会从暂停的位置继续执行。例如:
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b

使用生成器函数

fib_gen = fibonacci()
for _ in range(10):
print(next(fib_gen))
在上述代码中,fibonacci函数是一个生成器函数,它会无限地生成斐波那契数列。
生成器的方法
● next():用于获取生成器的下一个值。例如在上述斐波那契数列的生成器中,next(fib_gen)就可以获取下一个斐波那契数。
● send():可以向生成器发送值,并从yield表达式处继续执行。例如:
def generator():
value = yield 1
yield value

gen = generator()
print(next(gen))
print(gen.send(2))
在上述代码中,首先通过next(gen)启动生成器,执行到第一个yield语句,返回1。然后通过gen.send(2)向生成器发送值2,这个值会赋给value变量,然后继续执行到下一个yield语句,返回2。
● close():用于关闭生成器。关闭后的生成器再调用next()或send()会抛出StopIteration异常。
生成器的应用场景
● 处理大型数据集:当处理大型文件或数据集时,生成器可以逐行或逐个元素地处理数据,而不需要将整个数据集加载到内存中,从而节省内存空间。例如,读取一个超大的文本文件:
def read_large_file(file_path):
with open(file_path, ‘r’) as file:
for line in file:
yield line

使用生成器逐行读取文件

for line in read_large_file(‘large_file.txt’):
print(line)
● 实现无限序列:如生成无限的质数序列、随机数序列等。比如生成一个无限的随机数生成器:
import random

def random_number_generator():
while True:
yield random.random()

使用无限随机数生成器

rand_gen = random_number_generator()
for _ in range(10):
print(next(rand_gen))
● 协同程序:生成器可以用于实现简单的协同程序,多个生成器之间可以通过send()和yield进行协作和通信。

迭代器
可迭代对象Iterable:凡是可作用于for循环的对象都是Iterable类型。直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function。这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
可以使用isinstance()判断一个对象是否是Iterable对象。

迭代器Iterator:凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列。迭代器可以被next()函数调用并不断返回下一个值的对象称为迭代器。可以使用isinstance()判断一个对象是否是Iterator对象。

Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
Python的for循环本质上就是通过不断调用next()函数实现的。
for x in [1, 2, 3, 4, 5]:
pass

等价于下面的代码

首先获得Iterator对象:

it = iter([1, 2, 3, 4, 5])

循环:

while True:
try:
# 获得下一个值:
x = next(it)
except StopIteration:
# 遇到StopIteration就退出循环
break
函数式编程
高阶函数
map()和reduce()

高阶函数 reduce

from functools import reduce
def add(x, y):
return x + y
print(reduce(add, [1, 3, 5, 7, 9]))

DIGITS = {‘0’: 0, ‘1’: 1, ‘2’: 2, ‘3’: 3, ‘4’: 4, ‘5’: 5, ‘6’: 6, ‘7’: 7, ‘8’: 8, ‘9’: 9}
def str2int(s):
def fn(x, y):
return x * 10 + y
def char2num(s):
return DIGITS[s]
return reduce(fn, map(char2num, s))
print(str2int(‘12345’))
【例】利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字

利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字

def normalize(name):
return name.capitalize()
L1 = [‘adam’, ‘LISA’, ‘barT’]
L2 = list(map(normalize, L1))
print(L2)
【例】Python提供的sum()函数可以接受一个list并求和,请编写一个prod()函数,可以接受一个list并利用reduce()求积

Python提供的sum()函数可以接受一个list并求和,请编写一个prod()函数,可以接受一个list并利用reduce()求积

def prod(L):
return reduce(lambda x, y: x * y, L)
print(‘3 * 5 * 7 * 9 =’, prod([3, 5, 7, 9]))
if prod([3, 5, 7, 9]) == 945:
print(‘测试成功!’)
else:
print(‘测试失败!’)
【例】利用map和reduce编写一个str2float函数,把字符串’123.456’转换成浮点数123.456

利用map和reduce编写一个str2float函数,把字符串’123.456’转换成浮点数123.456

from functools import reduce

定义 DIGITS 字典,把字符映射为对应的数字

DIGITS = {‘0’: 0, ‘1’: 1, ‘2’: 2, ‘3’: 3, ‘4’: 4, ‘5’: 5, ‘6’: 6, ‘7’: 7, ‘8’: 8, ‘9’: 9}

def str2float(s):
def fn(x, y):
return x * 10 + y

def char2num(s):return DIGITS[s]n = s.index('.')
s1 = s[:n]
s2 = s[n + 1:]
return reduce(fn, map(char2num, s1)) + reduce(fn, map(char2num, s2)) / 10 ** len(s2)

print(‘str2float(‘123.456’) =’, str2float(‘123.456’))
if abs(str2float(‘123.456’) - 123.456) < 0.00001:
print(‘测试成功!’)
else:
print(‘测试失败!’)
返回函数
返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:
def count():
def f(j):
def g():
return j*j
return g
fs = []
for i in range(1, 4):
fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
return fs
f1, f2, f3 = count()

使用闭包时,对外层变量赋值前,需要先使用nonlocal声明该变量不是当前函数的局部变量。
def inc():
x = 0
def fn():
# nonlocal x
x = x + 1
return x
return fn

f = inc()
print(f()) # 1
print(f()) # 2
装饰器
在 Python 里,装饰器是一种很强大且实用的语法特性,它可以在不修改原有函数代码的基础上,为函数添加额外的功能。
你可以把装饰器想象成是一个 “包装器”,它就像给函数穿上了一件 “外套”,让函数拥有了新的能力,但函数本身的核心功能并没有改变。装饰器本质上是一个函数,这个函数接收另一个函数作为参数,并且返回一个新的函数。
下面是一个简单的装饰器示例,用来记录函数的执行时间:
import time

定义一个装饰器函数

def timer_decorator(func):
def wrapper():
# 记录函数开始执行的时间
start_time = time.time()
# 调用被装饰的函数
result = func()
# 记录函数结束执行的时间
end_time = time.time()
# 计算函数执行所花费的时间
execution_time = end_time - start_time
print(f"函数 {func.name} 执行花费了 {execution_time} 秒。")
return result
return wrapper

定义一个普通函数,并使用装饰器进行装饰

@timer_decorator
def my_function():
# 模拟一个耗时操作
time.sleep(2)
return “函数执行完毕”

调用被装饰后的函数

result = my_function()
print(result)
装饰器函数 timer_decorator:它接收一个函数 func 作为参数,这个 func 就是我们要装饰的函数。在 timer_decorator 内部,定义了一个新的函数 wrapper。wrapper 函数里记录了函数开始和结束的时间,计算出执行时间并打印出来,然后调用 func 函数并返回其结果。最后,timer_decorator 返回 wrapper 函数。
被装饰的函数 my_function:在定义 my_function 时,使用 @timer_decorator 语法糖,这就相当于 my_function = timer_decorator(my_function)。也就是说,把 my_function 函数作为参数传递给 timer_decorator 函数,然后用返回的新函数 wrapper 覆盖原来的 my_function 函数。
调用 my_function:调用 my_function 时,实际上调用的是 wrapper 函数。wrapper 函数会先记录时间,调用原来的 my_function 函数,再记录结束时间,计算并打印执行时间,最后返回 my_function 的执行结果。
如果被装饰的函数带有参数,那么装饰器里的 wrapper 函数也需要接收相应的参数,并传递给被装饰的函数。示例如下:
def timer_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
execution_time = end_time - start_time
print(f"函数 {func.name} 执行花费了 {execution_time} 秒。")
return result
return wrapper

@timer_decorator
def add_numbers(a, b):
return a + b

result = add_numbers(3, 5)
print(result)
在这个例子中,wrapper 函数使用 *args 和 **kwargs 来接收任意数量的位置参数和关键字参数,并将它们传递给 add_numbers 函数。
偏函数
在 Python 里,偏函数是一种很实用的工具,它能帮我们简化函数调用时的参数传递过程,让代码变得更加简洁明了。想象一下,你有一个函数,每次调用它的时候,有几个参数的值总是固定不变的。要是每次调用都得把这些固定的参数再写一遍,就会很麻烦。偏函数就像是一个 “预设置器”,它可以把函数的某些参数预先设置好固定的值,这样在后续调用这个函数时,就不用再重复传入这些固定的参数了。
下面通过一个例子来看看偏函数是怎么使用的。Python 的 int() 函数可以把字符串转换为整数,并且可以指定进制,默认是十进制。现在我们经常需要把二进制字符串转换为整数,就可以使用偏函数来简化这个过程:
from functools import partial

定义一个偏函数,将 int 函数的 base 参数预先设置为 2

int2 = partial(int, base=2)

正常使用 int 函数将二进制字符串转换为整数

result1 = int(‘1010’, base=2)
print(result1)

使用偏函数 int2 将二进制字符串转换为整数

result2 = int2(‘1010’)
print(result2)
导入 partial 函数:partial 函数位于 functools 模块中,所以我们需要使用 from functools import partial 来导入它。创建偏函数 int2:partial(int, base=2) 表示创建一个偏函数 int2,它实际上是对 int 函数的一个封装,并且把 int 函数的 base 参数预先设置为 2。也就是说,以后调用 int2 函数时,默认就是以二进制的方式来转换字符串。正常调用 int 函数和使用偏函数 int2:result1 = int(‘1010’, base=2) 是正常使用 int 函数,明确指定 base 参数为 2,将二进制字符串 ‘1010’ 转换为整数。result2 = int2(‘1010’) 是使用偏函数 int2,由于 int2 已经把 base 参数预先设置为 2 了,所以调用时只需要传入要转换的字符串 ‘1010’ 就可以了。

模块
你可以把模块想象成一个 “代码仓库”,里面存放着各种函数、类和变量。一个 Python 文件(以 .py 为扩展名)就是一个模块,这个文件里可以包含你编写的各种代码。例如,有一个文件叫 math_utils.py,里面可能定义了一些用于数学计算的函数,那么 math_utils.py 就是一个模块。
在 Python 中,使用 import 语句来导入模块。有几种不同的导入方式:

导入整个模块

import math

使用模块中的函数

result = math.sqrt(16)
print(result)

-----------------------

导入模块中的特定函数或类

from math import sqrt

直接使用导入的函数

result = sqrt(16)
print(result)

-----------------------

导入模块并给模块起别名

import math as m

使用别名调用模块中的函数

result = m.sqrt(16)
print(result)
模块搜索路径
当你使用 import 语句导入模块时,Python 会按照一定的顺序在一些特定的路径下查找这个模块。默认情况下,Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块,这些路径可以通过 sys.path 来查看:
import sys

print(sys.path)

[‘/Users/poyun/Documents/学习/learning/python’, ‘/Users/poyun/.pyenv/versions/3.13.1/lib/python313.zip’, ‘/Users/poyun/.pyenv/versions/3.13.1/lib/python3.13’, ‘/Users/poyun/.pyenv/versions/3.13.1/lib/python3.13/lib-dynload’, ‘/Users/poyun/.pyenv/versions/3.13.1/lib/python3.13/site-packages’]

sys.path 是一个列表,包含了 Python 查找模块的路径,其中包括 Python 的标准库路径、当前工作目录等。如果要导入的模块不在这些路径中,Python 就会报错找不到模块。
如果我们要添加自己的搜索目录,有两种方法:一是直接修改sys.path,添加要搜索的目录。这种方法是在运行时修改,运行结束后失效。第二种方法是设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。设置方式与设置Path环境变量类似。注意只需要添加我们自己的搜索路径,Python本身的搜索路径不受影响。
import sys
sys.path.append(‘/Users/michael/my_py_scripts’)
安装第三方模块
在Python中,安装第三方模块,是通过包管理工具pip完成的。一般来说,第三方库都会在Python官方的pypi.python.org网站注册,要安装一个第三方库,必须先知道该库的名称,可以在官网或者pypi上搜索,比如Pillow的名称叫Pillow,因此,安装Pillow的命令就是:
pip install Pillow
可以从Anaconda官网下载GUI安装包,安装包有500~600M,所以需要耐心等待下载。下载后直接安装,Anaconda会把系统Path中的python指向自己自带的Python,并且,Anaconda安装的第三方模块会安装在Anaconda自己的路径下,不影响系统已安装的Python目录。安装好Anaconda后,重新打开命令行窗口,输入python,可以看到Anaconda的信息:
────────────────────────────────────────────────────────┐
│Command Prompt - python - □ x │
├────────────────────────────────────────────────────────┤
│Microsoft Windows [Version 10.0.0] │
│© 2015 Microsoft Corporation. All rights reserved. │
│ │
│C:> python │
│Python 3.6.3 |Anaconda, Inc.| … on win32 │
│Type “help”, … for more information. │
│>>> import numpy │
│>>> _ │
│ │
└────────────────────────────────────────────────────────┘

类和实例
Python 和静态语言不同,Python允许对实例变量绑定任何数据,也就是说,对于两个实例变量,虽然它们都是同一个类的不同实例,但拥有的变量名称都可能不同。
像 Java、C++ 这类静态语言,在定义类的时候,就必须明确规定类有哪些属性(也就是实例变量),而且一旦定义好,每个实例都只能拥有这些规定好的属性,不能随意增减。就好比建房子之前先设计好图纸,每个房间的用途都定好了,建好后不能随便在房子里多隔出一个房间或者拆掉一个房间。
Python 和静态语言不同,它非常灵活。在 Python 里,创建类的实例之后,可以随时给这个实例添加新的变量,也可以删除已有的变量,不用像静态语言那样受事先定义的限制。
class Person:
def init(self, name):
self.name = name

创建两个 Person 类的实例

p1 = Person(“小明”)
p2 = Person(“小红”)

给 p1 实例添加一个新的实例变量 age

p1.age = 20

尝试访问 p2 的 age 属性,会报错,因为 p2 没有这个属性

try:
print(p2.age)
except AttributeError:
print(“p2 没有 age 这个实例变量”)

打印 p1 的 age 属性

print(f"p1 的 age 属性值为: {p1.age}")
实例变量是类的实例对象所拥有的变量。类就像是一个模板,根据这个模板创建出来的具体对象就是实例,每个实例都可以有自己独特的数据,这些数据就是实例变量。例如 “人” 是一个类,“小明” 和 “小红” 是 “人” 这个类的两个实例,“小明的身高”“小红的体重” 就是他们各自的实例变量。
访问限制
在 Python 里,面向对象的访问限制主要是用来控制类中属性和方法的访问权限,也就是决定哪些属性和方法可以在类的外部被访问、修改,哪些只能在类的内部使用。Python 不像其他一些编程语言(如 Java)有严格的访问控制关键字(像 private、protected 等),它通过命名约定来实现访问限制。
公开访问(Public)
公开访问的属性和方法是没有任何访问限制的,它们可以在类的内部和外部自由地被访问和调用。在 Python 中,默认情况下,所有的属性和方法都是公开的。
class Person:
def init(self, name):
# 公开属性
self.name = name

# 公开方法
def say_hello(self):print(f"Hello, my name is {self.name}.")

创建对象

p = Person(“Alice”)

可以在类外部直接访问公开属性

print(p.name)

可以在类外部直接调用公开方法

p.say_hello()
self.name 是一个公开属性,在类的外部可以直接访问。say_hello 是一个公开方法,在类的外部也可以直接调用。
受保护访问(Protected)
在 Python 中,通过在属性或方法名前加一个下划线 _ 来表示这是一个受保护的成员。虽然这只是一种命名约定,实际上并不能真正限制外部访问,但它是一种提示,告诉开发者这个成员应该只在类的内部或子类中使用。
class Animal:
def init(self, species):
# 受保护属性
self._species = species

# 受保护方法
def _print_species(self):print(f"Species: {self._species}")

class Dog(Animal):
def show_info(self):
# 子类可以访问父类的受保护属性和方法
self._print_species()

创建对象

dog = Dog(“Canine”)

理论上不建议在类外部直接访问受保护属性,但实际上可以访问

print(dog._species)
dog.show_info()
self._species 是一个受保护属性,_print_species 是一个受保护方法。在子类 Dog 中可以访问父类 Animal 的受保护属性和方法。虽然在类的外部也可以访问受保护成员,但这不符合编程规范,不建议这么做。
私有访问(Private)
在 Python 中,通过在属性或方法名前加两个下划线 __ 来表示这是一个私有成员。私有成员只能在类的内部访问,在类的外部无法直接访问。
class BankAccount:
def init(self, balance):
# 私有属性
self.__balance = balance

# 公开方法,用于访问私有属性
def get_balance(self):return self.__balance# 公开方法,用于修改私有属性
def deposit(self, amount):self.__balance += amount

创建对象

account = BankAccount(1000)

不能在类外部直接访问私有属性

print(account.__balance) # 这行代码会报错

通过公开方法访问私有属性

print(account.get_balance())

通过公开方法修改私有属性

account.deposit(500)
print(account.get_balance())
self.__balance 是一个私有属性,在类的外部无法直接访问。可以通过类内部的公开方法(如 get_balance 和 deposit)来访问和修改私有属性。

【拓展】双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。不能直接访问__name是因为Python解释器对外把__name变量改成了_Student__name,所以,仍然可以通过_Student__name来访问__name变量。但是强烈建议你不要这么干,因为不同版本的Python解释器可能会把__name改成不同的变量名。总的来说就是,Python本身没有任何机制阻止你干坏事,一切全靠自觉。

继承和多态
继承是面向对象编程中的一个重要特性,就好比现实生活中子女会继承父母的一些特征和能力。在 Python 里,一个类(子类)可以继承另一个类(父类)的属性和方法。通过继承,子类可以复用父类的代码,同时还能添加自己独特的属性和方法,或者对父类的方法进行修改。
多态也是面向对象编程的重要特性之一,简单来说,多态就是 “多种形态”。在 Python 里,多态指的是不同的对象对同一个方法可以有不同的实现方式。多态可以让代码更加灵活和可扩展,提高代码的复用性。

定义一个父类 Animal

class Animal:
def init(self, name):
self.name = name

def speak(self):print(f"{self.name} 发出了声音。")

定义一个子类 Dog,继承自 Animal 类

class Dog(Animal):
def speak(self):
print(f"{self.name} 汪汪汪。")

定义一个子类 Cat,继承自 Animal 类

class Cat(Animal):
def speak(self):
print(f"{self.name} 喵喵喵。")

创建对象

dog = Dog(“旺财”)
cat = Cat(“咪咪”)

调用 speak 方法

dog.speak()
cat.speak()

相关文章:

Python基础

https://www.w3schools.com/https://docs.python.org/3/ Python 介绍 Python是跨平台的&#xff0c;它可以运行在Windows、Mac和各种Linux/Unix系统上。在Windows上写Python程序&#xff0c;放到Linux上也是能够运行的。 要开始学习Python编程&#xff0c;首先就得把Python安装…...

基于Go语言 XTA AI聊天界面实现

项目开源地址: XTA-AI-SDK 人工智能技术的迅速发展&#xff0c;AI聊天应用变得越来越流行。本文将介绍如何使用Go语言和LCL库&#xff08; Lazarus Component Library&#xff09;创建一个功能丰富的AI聊天界面。项目主要包含以下模块&#xff1a; 项目背景 本项目旨在为开发…...

线上项目报错OOM常见原因、排查方式、解决方案

概述 OutOfMemoryError&#xff08;OOM&#xff09;是 Java 应用程序中常见的问题&#xff0c;通常是由于应用程序占用的内存超过了 JVM 分配的最大内存限制。在 Spring Boot 项目中&#xff0c;OOM 问题可能由多种原因引起。 1. OOM 的常见原因 OOM 通常由以下几种情况引起&…...

AI大模型零基础学习(6):多模态大模型实战——让AI看懂世界

从“文字交互”到“全感官认知”的维度突破 一、多模态大模型&#xff1a;AI的“五感觉醒” 1.1 基础概念重塑 单模态局限&#xff1a;传统大模型仅处理文本&#xff08;如ChatGPT&#xff09; 多模态进化&#xff1a; 输入&#xff1a;支持文本、图像、音频、视频、3D模型 …...

基于Spring Boot+Vue的宠物服务管理系统(源码+文档)

项目简介 宠物服务管理系统实现了以下功能&#xff1a; 基于Spring BootVue的宠物服务管理系统的主要使用者分为用户管理模块&#xff0c;由于系统运行在互联网络中&#xff0c;一些游客或者病毒恶意进行注册&#xff0c;产生大量的垃圾用户信息&#xff0c;管理员可以对这些…...

简要分析LeetCode树经典题目(Java)

目录 开场白 实战环节 准备工作 遍历问题 LeetCode144. 二叉树的前序遍历 方法一 方法二 LeetCode94. 二叉树的中序遍历 LeetCode145. 二叉树的后序遍历 方法一 方法二 LeetCode102. 二叉树的层序遍历 LeetCode103. 二叉树的锯齿形层序遍历 LeetCode107. 二叉树的…...

vue3开发打年兽功能

1.效果 WeChat_20250217192041 2.代码 2.1 index.vue <template><div class"pages"><TopNavigationYleftTitle"打年兽"ruleIconColor"#fff"backgroundImage""svgIpcn"backIcon4"gradientBackgroundColor&q…...

动手学Agent——Day2

文章目录 一、用 Llama-index 创建 Agent1. 测试模型2. 自定义一个接口类3. 使用 ReActAgent & FunctionTool 构建 Agent 二、数据库对话 Agent1. SQLite 数据库1.1 创建数据库 & 连接1.2 创建、插入、查询、更新、删除数据1.3 关闭连接建立数据库 2. ollama3. 配置对话…...

如何在 GitHub 中创建一个空目录 ?

GitHub 是开发人员必不可少的工具&#xff0c;它提供了存储、共享和协作代码的平台。一个常见的问题是如何在 GitHub 存储库中创建一个空目录或文件夹。GitHub 不支持直接创建空目录。但是&#xff0c;有一种解决方法是使用一个虚拟文件&#xff0c;通常是一个 .gitkeep 文件。…...

3. 导入官方dashboard

官方dashboard&#xff1a;https://grafana.com/grafana/dashboards 1. 点击仪表板 - 新建 - 导入 注&#xff1a;有网络的情况想可以使用ID&#xff0c;无网络情况下使用仪表板josn文件 2. 在官方dashboard网页上选择符合你现在数据源的dashboard - 点击进入 3. 下拉网页选…...

前端知识速记--HTML篇:HTML5的新特性

前端知识速记–HTML篇&#xff1a;HTML5的新特性 一、语义化标签 HTML5引入了许多新的语义化标签&#xff0c;如 <header>、<footer>、<article>、<section> 等。这些标签不仅提高了网页的可读性和结构性&#xff0c;还有助于SEO&#xff08;搜索引擎…...

【数据分享】1929-2024年全球站点的逐年降雪深度数据(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2024年全球气象站…...

鸿蒙面试题

1.0penHarmony的系统架构是怎样的? 2.电话服务的框架? 3.OpenHarmony与HarmonyOS有啥区别?...

pdf-extract-kit paddle paddleocr pdf2markdown.py(效果不佳)

GitHub - opendatalab/PDF-Extract-Kit: A Comprehensive Toolkit for High-Quality PDF Content Extraction https://github.com/opendatalab/PDF-Extract-Kit pdf2markdown.py 运行遇到的问题&#xff1a; 错误&#xff1a; -------------------------------------- C Tra…...

基于STM32、HAL库、RX8025T(I2C接口)驱动程序设计

一、简介: RX8025T 是一款低功耗、高精度的实时时钟芯片,具有以下特性: I2C 接口通信 内置 32.768 kHz 晶振 提供秒、分、时、日、月、年等时间信息 支持温度补偿,提高时间精度 低功耗设计,适合电池供电的应用 二、I2C初始化: #include "stm32l4xx_hal.h&…...

基于Ubuntu+vLLM+NVIDIA T4高效部署DeepSeek大模型实战指南

一、 前言&#xff1a;拥抱vLLM与T4显卡的强强联合 在探索人工智能的道路上&#xff0c;如何高效地部署和运行大型语言模型&#xff08;LLMs&#xff09;一直是一个核心挑战。尤其是当我们面对资源有限的环境时&#xff0c;这个问题变得更加突出。原始的DeepSeek-R1-32B模型虽…...

【Go语言快速上手】第二部分:Go语言进阶之并发编程

文章目录 一、并发编程1. goroutine&#xff1a;创建和调度 goroutine2. channel&#xff1a;无缓冲 channel、有缓冲 channel、select 语句2.1 无缓冲 channel2.2 有缓冲 channel2.3 select 语句 3. sync 包&#xff1a;Mutex、RWMutex、WaitGroup 等同步原语3.1 Mutex&#x…...

《机器学习数学基础》补充资料:四元数、点积和叉积

《机器学习数学基础》第1章1.4节介绍了内积、点积的有关概念&#xff0c;特别辨析了内积空间、欧几里得空间&#xff1b;第4章4.1.1节介绍了叉积的有关概念&#xff1b;4.1.2节介绍了张量积&#xff08;也称外积&#xff09;的概念。 以上这些内容&#xff0c;在不同资料中&…...

蓝桥杯篇---IAP15F2K61S2矩阵键盘

文章目录 前言简介矩阵键盘的工作原理1.行扫描2.检测列状态3.按键识别 硬件连接1.行线2.列线 矩阵键盘使用步骤1.初始化IO口2.扫描键盘3.消抖处理4.按键识别 示例代码&#xff1a;4x4矩阵键盘扫描示例代码&#xff1a;优化后的矩阵键盘扫描注意事项1.消抖处理2.扫描频率3.IO口配…...

通过小型语言模型尽可能简单地解释 Transformer

介绍 在过去的几年里&#xff0c;我阅读了无数关于 Transformer 网络的文章&#xff0c;观看了许多视频。其中大部分都非常好&#xff0c;但我很难理解 Transformer 架构&#xff0c;而其背后的主要直觉&#xff08;上下文敏感嵌入&#xff09;则更容易掌握。在做演讲时&#…...

GcExcel

GcExcel 简述:GcExcel Java 是一款基于 Java 平台,支持批量创建、编辑、打印、导入/导出Excel文件的服务端表格组件,能够高性能处理和高度兼容 Excel。功能特性(图1)文档查询(图2)...

封装红黑树实现map和set

" 喜欢了你十年&#xff0c;却用整个四月&#xff0c;编织了一个不爱你的谎言。 " 目录 1 源码及其框架分析 2 模拟实现map和set 2.1 实现出复用红黑树的框架 2.2 支持iterator迭代器的实现 2.2.1 代码实现和--这两个运算符 2.3 map支持[ ] Hello&#xff0c;大家…...

Redis进阶使用

在日常工作中&#xff0c;使用Redis有什么需要注意的&#xff1f; 设置合适的过期时间。尽量避免大key问题&#xff0c;避免用字符串存储过大的数据&#xff1b;避免集合的数据量太大&#xff0c;要定期清除。 常用的数据结构有哪些&#xff1f;用在什么地方&#xff1f; 按…...

【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第四节】

ISO 14229-1:2023 UDS诊断服务测试用例全解析&#xff08;Read DTC Information0x19服务&#xff09; 作者&#xff1a;车端域控测试工程师 更新日期&#xff1a;2025年2月13日 关键词&#xff1a;UDS诊断协议、0x19服务、DTC信息读取、ISO 14229-1:2023、ECU测试 一、服务功能…...

使用Node.js进行串口通信

目录 一、 安装 serialport 库二.、实现方法1.打开串口并配置参数2. 向串口传递信息3. 接收串口信息4. 处理错误5. 关闭串口6. 使用解析器7. 获取串口列表 三、 完整示例代码 一、 安装 serialport 库 首先&#xff0c;需要安装 serialport 库。可以通过 npm 安装&#xff1a;…...

vue3+elementplus新建项目

更新node.js和npm node.js官网更新指南 可以根据自己的操作系统进行选择 我的电脑操作系统是mac os所以我的步骤如下 # Download and install nvm: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash# in lieu of restarting the shell \. &…...

【网络安全 | 漏洞挖掘】跨子域账户合并导致的账户劫持与删除

未经许可,不得转载。 文章目录 概述正文漏洞成因概述 在对目标系统进行安全测试时,发现其运行着两个独立的域名——一个用于司机用户,一个用于开发者/企业用户。表面上看,这两个域名各自独立管理账户,但测试表明它们在处理电子邮件变更时存在严重的逻辑漏洞。该漏洞允许攻…...

VLSM基础知识

VLSM&#xff08;Variable Length Subnet Mask&#xff0c;变长子网掩码&#xff09;是一种更灵活的子网划分技术&#xff0c;允许在同一网络中使用不同长度的子网掩码&#xff0c;以满足不同子网对主机数量的需求&#xff0c;最大化IP地址利用率。 一、基础概念 传统子网划分…...

小小小病毒(3)(~_~|)

一分耕耘一分收获 声明&#xff1a; 仅供损害电脑&#xff0c;不得用于非法。损坏电脑&#xff0c;作者一律不负责。此作为作者原创&#xff0c;转载请经过同意。 欢迎来到小小小病毒&#xff08;3&#xff09; 感谢大家的支持 还是那句话&#xff1a;上代码&#xff01; …...

WebRTC与EasyRTC:开启智能硬件音视频通讯的全新旅程

在当今数字化时代&#xff0c;音视频通讯技术正以前所未有的速度革新着我们的生活与工作方式。WebRTC与EasyRTC作为这一领域的佼佼者&#xff0c;正携手为智能硬件的音视频通讯注入强大动力&#xff0c;开启全新的篇章。 一、WebRTC与智能硬件融合的崭新趋势 WebRTC技术&…...

Lua 数据库访问

Lua 数据库访问 引言 Lua 是一种轻量级的编程语言,因其简洁性和高效性,常被用于游戏开发、嵌入系统和应用程序开发。在许多情况下,数据库访问是应用程序的核心功能之一。本文将深入探讨在 Lua 中如何进行数据库访问,包括连接数据库、执行查询、处理结果以及异常处理等。 …...

rtsp rtmp 跟 http 区别

SDP 一SDP介绍 1. SDP的核心功能 会话描述&#xff1a;定义会话的名称、创建者、时间范围、连接地址等全局信息。媒体协商&#xff1a;明确媒体流的类型&#xff08;如音频、视频&#xff09;、传输协议&#xff08;如RTP/UDP&#xff09;、编码格式&#xff08;如H.264、Op…...

蓝桥杯篇---IAP15F2K61S2串口

文章目录 前言简介串口通信的基本参数1.波特率2.数据位3.停止位4.校验位 串口相关寄存器1.SCON2.SBUF3.PCON4.TMOD5.TH1/TL1 串口使用步骤1.配置波特率2.配置串口模式3.使能串口中断4.发送数据5.接收数据6.处理中断 示例代码&#xff1a;串口发送与接收示例代码&#xff1a;串口…...

Linux 远程文件复制传输-----scp/rsync/sftp

scp&#xff08;Secure Copy Protocol&#xff09;是基于 SSH 的安全文件传输工具&#xff0c;可用于在本地和远程计算机之间复制文件或目录。 1. scp&#xff08;基于 SSH 复制文件&#xff09; a. 复制文件到远程 从本地复制到远程 scp localfile.txt userremote_host:/remo…...

企业文件安全:零信任架构下的文件访问控制

在企业数字化转型的进程中&#xff0c;传统的文件访问控制模型已难以满足日益复杂的网络安全需求。零信任架构作为一种新兴的安全理念&#xff0c;为企业的文件安全访问提供了全新的解决方案。 一、传统文件访问控制的局限性 传统的文件访问控制主要基于网络边界&#xff0c;…...

用deepseek学大模型05-线性回归

deepseek.com:多元线性回归的目标函数&#xff0c;损失函数&#xff0c;梯度下降 标量和矩阵形式的数学推导&#xff0c;pytorch真实能跑的代码案例以及模型,数据&#xff0c;预测结果的可视化展示&#xff0c; 模型应用场景和优缺点&#xff0c;及如何改进解决及改进方法数据推…...

2009年下半年软件设计师上午真题的知识点整理(附真题及答案解析)

以下是2009年下半年软件设计师上午真题的知识点分类整理&#xff0c;涉及定义的详细解释&#xff0c;供背诵记忆。 1. 计算机组成原理 CPU与存储器的访问。 Cache的作用: 提高CPU访问主存数据的速度&#xff0c;减少访问延迟。存储器的层次结构: 包括寄存器、Cache、主存和辅存…...

Element Plus table 去除行hover效果

需求&#xff1a; 给table的指定行设置高亮背景色且去除掉这些行的hover效果 思路&#xff1a; 给指定行设置css类名选择需要设置高亮的行的单元格&#xff0c;设置鼠标禁用属性让高亮行继承父元素的背景色 考虑到表格的第一列是勾选框&#xff0c;因此仅选择 tr 下除了第一…...

2010年下半年软件设计师考试上午真题的知识点整理(附真题及答案解析)

以下是2010年下半年软件设计师考试上午真题的知识点分类整理&#xff0c;涉及定义的详细解释&#xff0c;供背诵记忆。 1. 计算机组成原理 CPU与存储器的访问。 Cache的作用: 提高CPU访问主存数据的速度&#xff0c;减少访问延迟。存储器的层次结构: 包括寄存器、Cache、主存和…...

Mac Golang 开发环境配置

Mac Golang 开发环境配置 Golang 介绍 Go&#xff08;又称Golang&#xff09;是Google开发的一种静态强类型、编译型、并发型&#xff0c;并具有垃圾回收功能的编程语言。 由罗伯特格瑞史莫&#xff0c;罗勃派克&#xff08;Rob Pike&#xff09;及肯汤普逊于2007年9月开始设计…...

计算机视觉中图像的基础认知

第一章&#xff1a;计算机视觉中图像的基础认知 第二章&#xff1a;计算机视觉&#xff1a;卷积神经网络(CNN)基本概念(一) 第三章&#xff1a;计算机视觉&#xff1a;卷积神经网络(CNN)基本概念(二) 第四章&#xff1a;搭建一个经典的LeNet5神经网络 一、图像/视频的基本属性…...

理解 WebGPU 中的 navigator.gpu 和 adapter:从浏览器到显卡的旅程

WebGPU 是一种现代图形 API&#xff0c;旨在为 Web 应用程序提供高性能的图形和计算功能。作为 WebGL 的继任者&#xff0c;WebGPU 提供了更底层的硬件访问和更高效的性能。在 WebGPU 开发中&#xff0c;navigator.gpu 是访问 WebGPU API 的入口点&#xff0c;而 adapter 则是浏…...

【ESP32 IDF】ESP32 linux 环境搭建

ESP32 linux 环境搭建 1. 开发环境2. linux指令 1. 开发环境 liunx镜像 liunx镜像地址 &#xff1a; https://mirrors.xjtu.edu.cn/ubuntu-releases/20.04.6/ubuntu-20.04.6-live-server-amd64.iso 有提示你装openssl&#xff0c;务必装上 2. linux指令 工具 sudo apt-get …...

react传递函数与回调函数原理

为什么 React 允许直接传递函数&#xff1f; 回调函数核心逻辑 例子&#xff1a;父组件控制 Modal 的显示与隐藏 // 父组件 (ParentComponent.tsx) import React, { useState } from react; import { Modal, Button } from antd; import ModalContent from ./ModalContent;co…...

目标检测IoU阈值全解析:YOLO/DETR模型中的精度-召回率博弈与工程实践指南

一、技术原理与数学本质 IoU计算公式&#xff1a; IoU \frac{Area\ of\ Overlap}{Area\ of\ Union} \frac{A ∩ B}{A ∪ B}阈值选择悖论&#xff1a; 高阈值&#xff08;0.6-0.75&#xff09;&#xff1a;减少误检&#xff08;FP↓&#xff09;但增加漏检&#xff08;FN↑…...

使用grafana v11 建立k线(蜡烛图)仪表板

先看实现的结果 沪铜主力合约 2025-02-12 的1分钟k线图 功能介绍: 左上角支持切换主力合约,日期,实现动态加载数据. 项目背景: 我想通过前端展示期货指定品种某1天的1分钟k线,类似tqsdk 的web_gui 生成图形化界面— TianQin Python SDK 3.7.8 文档 项目架构: 后端: fastap…...

Ubuntu下载安装Docker-Desktop

下载 Ubuntu | Docker Docs 预备工作 Ubuntu增加docker apt库-CSDN博客 安装 sudo apt-get updatesudo apt install gnome-terminal# sudo apt install -y docker-composesudo apt-get install ./docker-desktop-amd64.deb 测试 sudo docker run hello-worldHello from D…...

【大模型】DeepSeek 高级提示词技巧使用详解

目录 一、前言 二、DeepSeek 通用提示词技巧 2.1 DeepSeek 通用提示词技巧总结 三、DeepSeek 进阶使用技巧 3.1 DeepSeek一个特定角色的人设 3.1.1 为DeepSeek设置角色操作案例一 3.1.2 为DeepSeek设置角色操作案例二 3.2 DeepSeek开放人设升级 3.2.1 特殊的人设&#…...

23. AI-大语言模型

文章目录 前言一、LLM1. 简介2. 工作原理和结构3. 应用场景4. 最新研究进展5. 比较 二、Transformer架构1. 简介2. 基本原理和结构3. 应用场景4. 最新进展 三、开源1. 开源概念2. 开源模式3. 模型权重 四、再谈DeepSeek 前言 AI‌ 一、LLM LLM&#xff08;Large Language Mod…...

STM32的启动流程

启动模式 我们知道的复位方式有三种&#xff1a;上电复位&#xff0c;硬件复位和软件复位。当产生复位&#xff0c;并且离开复位状态后&#xff0c; CM33 内核做的第一件事就是读取下列两个 32 位整数的值&#xff1a; &#xff08;1&#xff09; 从地址 0x0000 0000 处取出堆…...