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是跨平台的,它可以运行在Windows、Mac和各种Linux/Unix系统上。在Windows上写Python程序,放到Linux上也是能够运行的。 要开始学习Python编程,首先就得把Python安装…...
基于Go语言 XTA AI聊天界面实现
项目开源地址: XTA-AI-SDK 人工智能技术的迅速发展,AI聊天应用变得越来越流行。本文将介绍如何使用Go语言和LCL库( Lazarus Component Library)创建一个功能丰富的AI聊天界面。项目主要包含以下模块: 项目背景 本项目旨在为开发…...
线上项目报错OOM常见原因、排查方式、解决方案
概述 OutOfMemoryError(OOM)是 Java 应用程序中常见的问题,通常是由于应用程序占用的内存超过了 JVM 分配的最大内存限制。在 Spring Boot 项目中,OOM 问题可能由多种原因引起。 1. OOM 的常见原因 OOM 通常由以下几种情况引起&…...
AI大模型零基础学习(6):多模态大模型实战——让AI看懂世界
从“文字交互”到“全感官认知”的维度突破 一、多模态大模型:AI的“五感觉醒” 1.1 基础概念重塑 单模态局限:传统大模型仅处理文本(如ChatGPT) 多模态进化: 输入:支持文本、图像、音频、视频、3D模型 …...
基于Spring Boot+Vue的宠物服务管理系统(源码+文档)
项目简介 宠物服务管理系统实现了以下功能: 基于Spring BootVue的宠物服务管理系统的主要使用者分为用户管理模块,由于系统运行在互联网络中,一些游客或者病毒恶意进行注册,产生大量的垃圾用户信息,管理员可以对这些…...
简要分析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 是开发人员必不可少的工具,它提供了存储、共享和协作代码的平台。一个常见的问题是如何在 GitHub 存储库中创建一个空目录或文件夹。GitHub 不支持直接创建空目录。但是,有一种解决方法是使用一个虚拟文件,通常是一个 .gitkeep 文件。…...
3. 导入官方dashboard
官方dashboard:https://grafana.com/grafana/dashboards 1. 点击仪表板 - 新建 - 导入 注:有网络的情况想可以使用ID,无网络情况下使用仪表板josn文件 2. 在官方dashboard网页上选择符合你现在数据源的dashboard - 点击进入 3. 下拉网页选…...
前端知识速记--HTML篇:HTML5的新特性
前端知识速记–HTML篇:HTML5的新特性 一、语义化标签 HTML5引入了许多新的语义化标签,如 <header>、<footer>、<article>、<section> 等。这些标签不仅提高了网页的可读性和结构性,还有助于SEO(搜索引擎…...
【数据分享】1929-2024年全球站点的逐年降雪深度数据(Shp\Excel\免费获取)
气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、能见度等指标,说到气象数据,最详细的气象数据是具体到气象监测站点的数据! 有关气象指标的监测站点数据,之前我们分享过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 运行遇到的问题: 错误: -------------------------------------- C Tra…...
基于STM32、HAL库、RX8025T(I2C接口)驱动程序设计
一、简介: RX8025T 是一款低功耗、高精度的实时时钟芯片,具有以下特性: I2C 接口通信 内置 32.768 kHz 晶振 提供秒、分、时、日、月、年等时间信息 支持温度补偿,提高时间精度 低功耗设计,适合电池供电的应用 二、I2C初始化: #include "stm32l4xx_hal.h&…...
基于Ubuntu+vLLM+NVIDIA T4高效部署DeepSeek大模型实战指南
一、 前言:拥抱vLLM与T4显卡的强强联合 在探索人工智能的道路上,如何高效地部署和运行大型语言模型(LLMs)一直是一个核心挑战。尤其是当我们面对资源有限的环境时,这个问题变得更加突出。原始的DeepSeek-R1-32B模型虽…...
【Go语言快速上手】第二部分:Go语言进阶之并发编程
文章目录 一、并发编程1. goroutine:创建和调度 goroutine2. channel:无缓冲 channel、有缓冲 channel、select 语句2.1 无缓冲 channel2.2 有缓冲 channel2.3 select 语句 3. sync 包:Mutex、RWMutex、WaitGroup 等同步原语3.1 Mutex&#x…...
《机器学习数学基础》补充资料:四元数、点积和叉积
《机器学习数学基础》第1章1.4节介绍了内积、点积的有关概念,特别辨析了内积空间、欧几里得空间;第4章4.1.1节介绍了叉积的有关概念;4.1.2节介绍了张量积(也称外积)的概念。 以上这些内容,在不同资料中&…...
蓝桥杯篇---IAP15F2K61S2矩阵键盘
文章目录 前言简介矩阵键盘的工作原理1.行扫描2.检测列状态3.按键识别 硬件连接1.行线2.列线 矩阵键盘使用步骤1.初始化IO口2.扫描键盘3.消抖处理4.按键识别 示例代码:4x4矩阵键盘扫描示例代码:优化后的矩阵键盘扫描注意事项1.消抖处理2.扫描频率3.IO口配…...
通过小型语言模型尽可能简单地解释 Transformer
介绍 在过去的几年里,我阅读了无数关于 Transformer 网络的文章,观看了许多视频。其中大部分都非常好,但我很难理解 Transformer 架构,而其背后的主要直觉(上下文敏感嵌入)则更容易掌握。在做演讲时&#…...
GcExcel
GcExcel 简述:GcExcel Java 是一款基于 Java 平台,支持批量创建、编辑、打印、导入/导出Excel文件的服务端表格组件,能够高性能处理和高度兼容 Excel。功能特性(图1)文档查询(图2)...
封装红黑树实现map和set
" 喜欢了你十年,却用整个四月,编织了一个不爱你的谎言。 " 目录 1 源码及其框架分析 2 模拟实现map和set 2.1 实现出复用红黑树的框架 2.2 支持iterator迭代器的实现 2.2.1 代码实现和--这两个运算符 2.3 map支持[ ] Hello,大家…...
Redis进阶使用
在日常工作中,使用Redis有什么需要注意的? 设置合适的过期时间。尽量避免大key问题,避免用字符串存储过大的数据;避免集合的数据量太大,要定期清除。 常用的数据结构有哪些?用在什么地方? 按…...
【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第四节】
ISO 14229-1:2023 UDS诊断服务测试用例全解析(Read DTC Information0x19服务) 作者:车端域控测试工程师 更新日期:2025年2月13日 关键词:UDS诊断协议、0x19服务、DTC信息读取、ISO 14229-1:2023、ECU测试 一、服务功能…...
使用Node.js进行串口通信
目录 一、 安装 serialport 库二.、实现方法1.打开串口并配置参数2. 向串口传递信息3. 接收串口信息4. 处理错误5. 关闭串口6. 使用解析器7. 获取串口列表 三、 完整示例代码 一、 安装 serialport 库 首先,需要安装 serialport 库。可以通过 npm 安装:…...
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(Variable Length Subnet Mask,变长子网掩码)是一种更灵活的子网划分技术,允许在同一网络中使用不同长度的子网掩码,以满足不同子网对主机数量的需求,最大化IP地址利用率。 一、基础概念 传统子网划分…...
小小小病毒(3)(~_~|)
一分耕耘一分收获 声明: 仅供损害电脑,不得用于非法。损坏电脑,作者一律不负责。此作为作者原创,转载请经过同意。 欢迎来到小小小病毒(3) 感谢大家的支持 还是那句话:上代码! …...
WebRTC与EasyRTC:开启智能硬件音视频通讯的全新旅程
在当今数字化时代,音视频通讯技术正以前所未有的速度革新着我们的生活与工作方式。WebRTC与EasyRTC作为这一领域的佼佼者,正携手为智能硬件的音视频通讯注入强大动力,开启全新的篇章。 一、WebRTC与智能硬件融合的崭新趋势 WebRTC技术&…...
Lua 数据库访问
Lua 数据库访问 引言 Lua 是一种轻量级的编程语言,因其简洁性和高效性,常被用于游戏开发、嵌入系统和应用程序开发。在许多情况下,数据库访问是应用程序的核心功能之一。本文将深入探讨在 Lua 中如何进行数据库访问,包括连接数据库、执行查询、处理结果以及异常处理等。 …...
rtsp rtmp 跟 http 区别
SDP 一SDP介绍 1. SDP的核心功能 会话描述:定义会话的名称、创建者、时间范围、连接地址等全局信息。媒体协商:明确媒体流的类型(如音频、视频)、传输协议(如RTP/UDP)、编码格式(如H.264、Op…...
蓝桥杯篇---IAP15F2K61S2串口
文章目录 前言简介串口通信的基本参数1.波特率2.数据位3.停止位4.校验位 串口相关寄存器1.SCON2.SBUF3.PCON4.TMOD5.TH1/TL1 串口使用步骤1.配置波特率2.配置串口模式3.使能串口中断4.发送数据5.接收数据6.处理中断 示例代码:串口发送与接收示例代码:串口…...
Linux 远程文件复制传输-----scp/rsync/sftp
scp(Secure Copy Protocol)是基于 SSH 的安全文件传输工具,可用于在本地和远程计算机之间复制文件或目录。 1. scp(基于 SSH 复制文件) a. 复制文件到远程 从本地复制到远程 scp localfile.txt userremote_host:/remo…...
企业文件安全:零信任架构下的文件访问控制
在企业数字化转型的进程中,传统的文件访问控制模型已难以满足日益复杂的网络安全需求。零信任架构作为一种新兴的安全理念,为企业的文件安全访问提供了全新的解决方案。 一、传统文件访问控制的局限性 传统的文件访问控制主要基于网络边界,…...
用deepseek学大模型05-线性回归
deepseek.com:多元线性回归的目标函数,损失函数,梯度下降 标量和矩阵形式的数学推导,pytorch真实能跑的代码案例以及模型,数据,预测结果的可视化展示, 模型应用场景和优缺点,及如何改进解决及改进方法数据推…...
2009年下半年软件设计师上午真题的知识点整理(附真题及答案解析)
以下是2009年下半年软件设计师上午真题的知识点分类整理,涉及定义的详细解释,供背诵记忆。 1. 计算机组成原理 CPU与存储器的访问。 Cache的作用: 提高CPU访问主存数据的速度,减少访问延迟。存储器的层次结构: 包括寄存器、Cache、主存和辅存…...
Element Plus table 去除行hover效果
需求: 给table的指定行设置高亮背景色且去除掉这些行的hover效果 思路: 给指定行设置css类名选择需要设置高亮的行的单元格,设置鼠标禁用属性让高亮行继承父元素的背景色 考虑到表格的第一列是勾选框,因此仅选择 tr 下除了第一…...
2010年下半年软件设计师考试上午真题的知识点整理(附真题及答案解析)
以下是2010年下半年软件设计师考试上午真题的知识点分类整理,涉及定义的详细解释,供背诵记忆。 1. 计算机组成原理 CPU与存储器的访问。 Cache的作用: 提高CPU访问主存数据的速度,减少访问延迟。存储器的层次结构: 包括寄存器、Cache、主存和…...
Mac Golang 开发环境配置
Mac Golang 开发环境配置 Golang 介绍 Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。 由罗伯特格瑞史莫,罗勃派克(Rob Pike)及肯汤普逊于2007年9月开始设计…...
计算机视觉中图像的基础认知
第一章:计算机视觉中图像的基础认知 第二章:计算机视觉:卷积神经网络(CNN)基本概念(一) 第三章:计算机视觉:卷积神经网络(CNN)基本概念(二) 第四章:搭建一个经典的LeNet5神经网络 一、图像/视频的基本属性…...
理解 WebGPU 中的 navigator.gpu 和 adapter:从浏览器到显卡的旅程
WebGPU 是一种现代图形 API,旨在为 Web 应用程序提供高性能的图形和计算功能。作为 WebGL 的继任者,WebGPU 提供了更底层的硬件访问和更高效的性能。在 WebGPU 开发中,navigator.gpu 是访问 WebGPU API 的入口点,而 adapter 则是浏…...
【ESP32 IDF】ESP32 linux 环境搭建
ESP32 linux 环境搭建 1. 开发环境2. linux指令 1. 开发环境 liunx镜像 liunx镜像地址 : https://mirrors.xjtu.edu.cn/ubuntu-releases/20.04.6/ubuntu-20.04.6-live-server-amd64.iso 有提示你装openssl,务必装上 2. linux指令 工具 sudo apt-get …...
react传递函数与回调函数原理
为什么 React 允许直接传递函数? 回调函数核心逻辑 例子:父组件控制 Modal 的显示与隐藏 // 父组件 (ParentComponent.tsx) import React, { useState } from react; import { Modal, Button } from antd; import ModalContent from ./ModalContent;co…...
目标检测IoU阈值全解析:YOLO/DETR模型中的精度-召回率博弈与工程实践指南
一、技术原理与数学本质 IoU计算公式: IoU \frac{Area\ of\ Overlap}{Area\ of\ Union} \frac{A ∩ B}{A ∪ B}阈值选择悖论: 高阈值(0.6-0.75):减少误检(FP↓)但增加漏检(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(Large Language Mod…...
STM32的启动流程
启动模式 我们知道的复位方式有三种:上电复位,硬件复位和软件复位。当产生复位,并且离开复位状态后, CM33 内核做的第一件事就是读取下列两个 32 位整数的值: (1) 从地址 0x0000 0000 处取出堆…...