既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
colors = ["black", "white"]
sizes = ["S", "M", "L"]
tshirts = ["{} {}".format(color, size) for color in colors for size in sizes]
tshirts
['black S', 'black M', 'black L', 'white S', 'white M', 'white L']
2、其他解析语法的例子
- 解析语法构造字典(字典推导)
squares = {i: i\*\*2 for i in range(10)}
for k, v in squares.items():
print(k, ": ", v)
0 : 0
1 : 1
2 : 4
3 : 9
4 : 16
5 : 25
6 : 36
7 : 49
8 : 64
9 : 81
- 解析语法构造集合(集合推导)
squares = {i\*\*2 for i in range(10)}
squares
{0, 1, 4, 9, 16, 25, 36, 49, 64, 81}
- 生成器表达式
squares = (i\*\*2 for i in range(10))
squares
<generator object <genexpr> at 0x000001DB37A58390>
colors = ["black", "white"]
sizes = ["S", "M", "L"]
tshirts = ("{} {}".format(color, size) for color in colors for size in sizes)
for tshirt in tshirts:
print(tshirt)
black S
black M
black L
white S
white M
white L
8.2.2 条件表达式
expr1 if condition else expr2
【例】将变量n的绝对值赋值给变量x
n = -10
if n >= 0:
x = n
else:
x = -n
x
10
n = -10
x = n if n>= 0 else -n
x
10
条件表达式和解析语法简单实用、运行速度相对更快一些,相信大家会慢慢的爱上它们
8.3 三大神器
8.3.1 生成器
ls = [i\*\*2 for i in range(1, 1000001)]
for i in ls:
pass
缺点:占用大量内存
生成器
(1)采用惰性计算的方式
(2)无需一次性存储海量数据
(3)一边执行一边计算,只计算每次需要的值
(4)实际上一直在执行next()操作,直到无值可取
1、生成器表达式
- 海量数据,不需存储
squares = (i\*\*2 for i in range(1000000))
for i in squares:
pass
- 求0~100的和
无需显示存储全部数据,节省内存
sum((i for i in range(101))) # 求和,里面是一个生成器
5050
2、生成器函数——yield
- 生产斐波那契数列
数列前两个元素为1,1 之后的元素为其前两个元素之和
def fib(max):
ls = []
n, a, b = 0, 1, 1
while n < max:
ls.append(a)
a, b = b, a + b
n = n + 1
return ls
fib(10)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
中间尝试
def fib(max):
n, a, b = 0, 1, 1
while n < max:
print(a)
a, b = b, a + b
n = n + 1
fib(10)
1
1
2
3
5
8
13
21
34
55
构造生成器函数
在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行
def fib(max):
n, a, b = 0, 1, 1
while n < max:
yield a
a, b = b, a + b
n = n + 1
fib(10)
<generator object fib at 0x000001BE11B19048>
for i in fib(10):
print(i)
1
1
2
3
5
8
13
21
34
55
8.3.2 迭代器
1、可迭代对象
可直接作用于for循环的对象统称为可迭代对象:Iterable
(1)列表、元组、字符串、字典、集合、文件
可以使用isinstance()判断一个对象是否是Iterable对象
from collections import Iterable
isinstance([1, 2, 3], Iterable)
True
isinstance({"name": "Sarah"}, Iterable)
True
isinstance('Python', Iterable)
True
(2)生成器
squares = (i\*\*2 for i in range(5))
isinstance(squares, Iterable)
True
生成器不但可以用于for循环,还可以被next()函数调用
print(next(squares))
print(next(squares))
print(next(squares))
print(next(squares))
print(next(squares))
0
1
4
9
16
直到没有数据可取,抛出StopIteration
print(next(squares))
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-66-f5163ac9e49b> in <module>
----> 1 print(next(squares))
StopIteration:
可以被next()函数调用并不断返回下一个值,直至没有数据可取的对象称为迭代器:Iterator
2、迭代器
可以使用isinstance()判断一个对象是否是Iterator对象
(1) 生成器都是迭代器
from collections import Iterator
squares = (i\*\*2 for i in range(5))
isinstance(squares, Iterator)
True
(2) 列表、元组、字符串、字典、集合不是迭代器
isinstance([1, 2, 3], Iterator)
False
可以通过iter(Iterable)创建迭代器
isinstance(iter([1, 2, 3]), Iterator)
True
for item in Iterable 等价于:
先通过iter()函数获取可迭代对象Iterable的迭代器
然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item
当遇到StopIteration的异常后循环结束
(3)zip enumerate 等itertools里的函数是迭代器
x = [1, 2]
y = ["a", "b"]
zip(x, y)
<zip at 0x1be11b13c48>
for i in zip(x, y):
print(i)
isinstance(zip(x, y), Iterator)
(1, 'a')
(2, 'b')
True
numbers = [1, 2, 3, 4, 5]
enumerate(numbers)
<enumerate at 0x1be11b39990>
for i in enumerate(numbers):
print(i)
isinstance(enumerate(numbers), Iterator)
(0, 1)
(1, 2)
(2, 3)
(3, 4)
(4, 5)
True
(4) 文件是迭代器
with open("测试文件.txt", "r", encoding = "utf-8") as f:
print(isinstance(f, Iterator))
True
(5)迭代器是可耗尽的
squares = (i\*\*2 for i in range(5))
for square in squares:
print(square)
0
1
4
9
16
for square in squares:
print(square)
再迭代不出来了,因为已经耗尽了
(6)range()不是迭代器
numbers = range(10)
isinstance(numbers, Iterator)
False
print(len(numbers)) # 有长度
print(numbers[0]) # 可索引
print(9 in numbers) # 可存在计算
next(numbers) # 不可被next()调用
10
0
True
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-76-7c59bf859258> in <module>
2 print(numbers[0]) # 可索引
3 print(9 in numbers) # 可存在计算
----> 4 next(numbers) # 不可被next()调用
TypeError: 'range' object is not an iterator
for number in numbers:
print(number)
0
1
2
3
4
5
6
7
8
9
不会被耗尽。
for number in numbers:
print(number)
0
1
2
3
4
5
6
7
8
9
可以称range()为懒序列
它是一种序列
但并不包含任何内存中的内容
而是通过计算来回答问题
8.3.3 装饰器
1、需求的提出
(1)需要对已开发上线的程序添加某些功能
(2)不能对程序中函数的源代码进行修改
(3)不能改变程序中函数的调用方式
比如说,要统计每个函数的运行时间
def f1():
pass
def f2():
pass
def f3():
pass
f1()
f2()
f3()
没问题,我们有装饰器!!!
2、函数对象
函数是Python中的第一类对象
(1)可以把函数赋值给变量
(2)对该变量进行调用,可实现原函数的功能
def square(x):
return x\*\*2
print(type(square)) # square 是function类的一个实例
<class 'function'>
pow_2 = square # 可以理解成给这个函数起了个别名pow\_2
print(pow_2(5))
print(square(5))
25
25
可以将函数作为参数进行传递
3、高阶函数
(1)接收函数作为参数
(2)或者返回一个函数
满足上述条件之一的函数称之为高阶函数
def square(x):
return x\*\*2
def pow\_2(fun):
return fun
f = pow_2(square)
f(8)
64
print(f == square)
True
4、 嵌套函数
在函数内部定义一个函数
def outer():
print("outer is running")
def inner():
print("inner is running")
inner()
outer()
outer is running
inner is running
5、闭包
def outer():
x = 1
z = 10
def inner():
y = x+100
return y, z
return inner
f = outer() # 实际上f包含了inner函数本身+outer函数的环境
print(f)
<function outer.<locals>.inner at 0x000001BE11B1D730>
print(f.__closure__) # \_\_closure\_\_属性中包含了来自外部函数的信息
for i in f.__closure__:
print(i.cell_contents)
(<cell at 0x000001BE0FDE06D8: int object at 0x00007FF910D59340>, <cell at 0x000001BE0FDE0A98: int object at 0x00007FF910D59460>)
1
10
res = f()
print(res)
(101, 10)
闭包:延伸了作用域的函数
如果一个函数定义在另一个函数的作用域内,并且引用了外层函数的变量,则该函数称为闭包
闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)
- 一旦在内层函数重新定义了相同名字的变量,则变量成为局部变量
def outer():
x = 1
def inner():
x = x+100
return x
return inner
f = outer()
f()
---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
<ipython-input-87-d2da1048af8b> in <module>
10
11 f = outer()
---> 12 f()
<ipython-input-87-d2da1048af8b> in inner()
3
4 def inner():
----> 5 x = x+100
6 return x
7
UnboundLocalError: local variable 'x' referenced before assignment
nonlocal允许内嵌的函数来修改闭包变量,表明它不是一个内部变量,采用外部函数的变量。
def outer():
x = 1
def inner():
nonlocal x
x = x+100
return x
return inner
f = outer()
f()
1
101
6、一个简单的装饰器
嵌套函数实现
import time
def timer(func):
def inner():
print("inner run")
start = time.time()
func()
end = time.time()
print("{} 函数运行用时{:.2f}秒".format(func.__name__, (end-start)))
return inner
def f1():
print("f1 run")
time.sleep(1)
f1 = timer(f1) # 包含inner()和timer的环境,如传递过来的参数func
f1()
inner run
f1 run
f1 函数运行用时1.00秒
语法糖
import time
def timer(func):
def inner():
print("inner run")
start = time.time()
func()
end = time.time()
print("{} 函数运行用时{:.2f}秒".format(func.__name__, (end-start)))
return inner
@timer # 相当于实现了f1 = timer(f1)
def f1():
print("f1 run")
time.sleep(1)
f1()
inner run
f1 run
f1 函数运行用时1.00秒
7、装饰有参函数
import time
def timer(func):
def inner(\*args, \*\*kwargs):
print("inner run")
start = time.time()
func(\*args, \*\*kwargs)
end = time.time()
print("{} 函数运行用时{:.2f}秒".format(func.__name__, (end-start)))
return inner
@timer # 相当于实现了f1 = timer(f1)
def f1(n):
print("f1 run")
time.sleep(n)
f1(2)
inner run
f1 run
f1 函数运行用时2.00秒
被装饰函数有返回值的情况
import time
def timer(func):
def inner(\*args, \*\*kwargs):
print("inner run")
start = time.time()
res = func(\*args, \*\*kwargs)
end = time.time()
print("{} 函数运行用时{:.2f}秒".format(func.__name__, (end-start)))
return res
return inner
@timer # 相当于实现了f1 = timer(f1)
def f1(n):
print("f1 run")
time.sleep(n)
return "wake up"
res = f1(2)
print(res)
inner run
f1 run
f1 函数运行用时2.00秒
wake up
8、带参数的装饰器
装饰器本身要传递一些额外参数
- 需求:有时需要统计绝对时间,有时需要统计绝对时间的2倍
def timer(method):
def outer(func):
def inner(\*args, \*\*kwargs):
print("inner run")
if method == "origin":
print("origin\_inner run")
start = time.time()
res = func(\*args, \*\*kwargs)
end = time.time()
print("{} 函数运行用时{:.2f}秒".format(func.__name__, (end-start)))
elif method == "double":
print("double\_inner run")
start = time.time()
res = func(\*args, \*\*kwargs)
end = time.time()
print("{} 函数运行双倍用时{:.2f}秒".format(func.__name__, 2\*(end-start)))
return res
return inner
return outer
@timer(method="origin") # 相当于timer = timer(method = "origin") f1 = timer(f1)
def f1():
print("f1 run")
time.sleep(1)
@timer(method="double")
def f2():
print("f2 run")
time.sleep(1)
f1()
print()
f2()
inner run
origin_inner run
f1 run
f1 函数运行用时1.00秒
inner run
double_inner run
f2 run
f2 函数运行双倍用时2.00秒
理解闭包是关键!!!
9、何时执行装饰器
- 一装饰就执行,不必等调用
func_names=[]
def find\_function(func):
print("run")
func_names.append(func)
return func
@find\_function
def f1():
print("f1 run")
@find\_function
def f2():
print("f2 run")
@find\_function
def f3():
print("f3 run")
run
run
run
for func in func_names:
print(func.__name__)
func()
print()
f1
f1 run
f2
f2 run
f3
f3 run
10、回归本源
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
return res
return inner
return outer
@timer(method=“origin”) # 相当于timer = timer(method = “origin”) f1 = timer(f1)
def f1():
print(“f1 run”)
time.sleep(1)
@timer(method=“double”)
def f2():
print(“f2 run”)
time.sleep(1)
f1()
print()
f2()
inner run
origin_inner run
f1 run
f1 函数运行用时1.00秒
inner run
double_inner run
f2 run
f2 函数运行双倍用时2.00秒
**理解闭包是关键!!!**
**9、何时执行装饰器**
* 一装饰就执行,不必等调用
func_names=[]
def find_function(func):
print(“run”)
func_names.append(func)
return func
@find_function
def f1():
print(“f1 run”)
@find_function
def f2():
print(“f2 run”)
@find_function
def f3():
print(“f3 run”)
run
run
run
for func in func_names:
print(func.name)
func()
print()
f1
f1 run
f2
f2 run
f3
f3 run
**10、回归本源**
[外链图片转存中...(img-JfqHHMkr-1715907926707)]
[外链图片转存中...(img-dQYXeBGM-1715907926708)]
[外链图片转存中...(img-FuKZpcZ6-1715907926709)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618658159)**