您的位置:首页 > 汽车 > 新车 > 硬件开发工程师简历_西安网站制作平台_谷歌关键词工具_汕头网页搜索排名提升

硬件开发工程师简历_西安网站制作平台_谷歌关键词工具_汕头网页搜索排名提升

2025/3/11 8:02:00 来源:https://blog.csdn.net/qq_39518871/article/details/145694626  浏览:    关键词:硬件开发工程师简历_西安网站制作平台_谷歌关键词工具_汕头网页搜索排名提升
硬件开发工程师简历_西安网站制作平台_谷歌关键词工具_汕头网页搜索排名提升

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()

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com