Python 之 进阶 学习
学习 Python 之 进阶学习
- 一切皆对象
- 1. 变量和函数皆对象
- 2. 模块和类皆对象
- 3. 对象的基本操作
- (1). 可以赋值给变量
- (2). 可以添加到集合中
- (3). 可以作为函数参数
- (4). 可以作为函数返回值返回
- 4. object, type, class之间的关系
- (1). object类
- (2).type类和type对象
- 闭包
- 1. 查看闭包
- (1). 查看闭包
- (2). 查看环境变量
- 2. 分析闭包
- 3. 闭包的用处
- Lambda 表达式
- 1. 匿名函数
- 2. 三元表达式
- 3. map类
- 4. map与lambda表达式结合使用
- 5. reduce函数
- ```reduce()```函数运算原理
- 6. filter函数
- 装饰器
- 1. 引例
- 2. 装饰器
- 3. 装饰器使用
- 4. 对带有参数的函数定义装饰器
- 5. 带有参数的装饰器的理解
- 6. 装饰器完整定义
- 7. 使用python装饰器保存内置变量的值
- 8. 数据类装饰器 dataclass
- 用字典映射代替switch case
- 列表推导式
- (1). 简单使用
- (2). 带有条件的列表推导式
- (3). 使用列表推导式创建元组
- (4). 字典列表推导式
- items()
- 字典推导字典
- 函数式编程
- 迭代器
- (1). 可迭代对象 和 迭代器
- (2). 自定义迭代器
- 生成器
- 海象运算符 :=
一切皆对象
1. 变量和函数皆对象
在python中, 所有的变量函数都是一个对象
print(type(1))
print(type(1.))
print(type(True))
print(type(None))
结果:
<class 'int'>
<class 'float'>
<class 'bool'>
<class 'NoneType'>
可以看出, 变量都是对象, 它们的类型都是class, 再看看函数
def f():passprint(type(f))
结果:
<class 'function'>
从上面的例子可以看出, 实际上函数就是一个对象, 那么函数可以当某个函数的参数和返回值了
2. 模块和类皆对象
就连模块和类都是对象
import sysprint(type(sys))
class A:passprint(type(A))
结果:
<class 'module'>
<class 'type'>
3. 对象的基本操作
(1). 可以赋值给变量
(2). 可以添加到集合中
(3). 可以作为函数参数
(4). 可以作为函数返回值返回
4. object, type, class之间的关系
(1). object类
object类
是所有类都要继承的一个基础类(父类)
class People:pass
print(People.__bases__)
结果:
(<class 'object'>,)
(2).type类和type对象
type()
函数查看变量类型, 但是type也是一个类, 还是一个对象
a = 1
print(type(a))
print(type(int))
结果:
<class 'int'>
<class 'type'>
因此, type类 生成 int类, int类 生成 1, 1 赋值给 a, 所以 a是int类的对象
所以, type类生成其他类
print(type.__bases__)
print(type(type))
print(type(object))
print(object.__bases__)
结果:
(<class 'object'>,)
<class 'type'>
<class 'type'>
()
可以看出, object类的父类是空
type类继承object类, type类又生成object类
type类生成type类
闭包
一个函数中的变量由其外部环境变量所决定的整体, 即函数 + 环境变量
闭包的意义: 保存了函数, 和函数定义时的变量
def func1():a = 5def ax2(x):return a * x * 2return ax2
a 是环境变量, ax2()是函数, 它们构成了一个闭包
1. 查看闭包
(1). 查看闭包
只有闭包才拥有内置属性__closure__
def func1():a = 5def ax2(x):return a * x * 2return ax2f = func1()
print(f.__closure__)
(<cell at 0x0000025E9917AF50: int object at 0x0000025E99010170>,)
(2). 查看环境变量
def func1():a = 5def ax2(x):return a * x * 2return ax2f = func1()
print(f.__closure__[0].cell_contents)
5
2. 分析闭包
函数里定义变量后不是闭包
def fun1():a = 5def fun2():b = 10return breturn fun2f = fun1()
print(f.__closure__)
None
def fun1():a = 5def fun2():return areturn fun2f = fun1()
print(f.__closure__)
(<cell at 0x0000025E9917AF50: int object at 0x0000025E99010170>,)
3. 闭包的用处
问题: 实现函数, 每次返回结果, 要在加入上一次的结果
假设开始 x = 0, 函数名是 add()
第一次 add(5), x = 5
第二次 add(10), x = 15
第三次 add(40), x = 40
x的值是在上一次的结果上叠加
- 不用闭包
x = 0def add(v):global xx += vreturn xprint('第一次:' , add(1))
print('第二次:' , add(5))
print('第三次:' , add(6))
print('第四次:' , add(10))
结果
第一次: 1
第二次: 6
第三次: 12
第四次: 22
- 使用闭包
x = 0def start(x):def add(v):nonlocal xx += vreturn xreturn addadd = start(x)
print('第一次:' , add(1))
print('第二次:' , add(5))
print('第三次:' , add(6))
print('第四次:' , add(10))
使用nonlocal
关键字
闭包的意义在于可以记录了上一次的值
Lambda 表达式
1. 匿名函数
没有函数名的函数
语法:
lambda parameter_list: expression
定义使用labmda
关键字
expression只能是表达式
def add(x, y):return x + yf = lambda x, y: x + y
print(f(1, 2))
2. 三元表达式
条件为真返回结果 if 条件 else 条件为假返回结果
x = 1
y = 6
print(x if x > y else y)
如果 x > y 返回 x 的值, 否则返回 y 的值
3. map类
map类接收两个参数, 一个是函数, 另一个是序列
map的使用方法是, 对序列中的每一个元素都进行前面函数的操作, 并把结果存放新的序列中, 最后返回
x = [1, 2, 3]def square(x):return x * xr = map(square, x)print('结果: ', list(r))
print('x: ', x)
这个代码相当于使用for循环
x = [1, 2, 3]def square(x):return x * x# r = map(square, x)
r = []
for v in x:r.append(square(v))print('结果: ', list(r))
print('x: ', x)
结果是一样的:
结果: [1, 4, 9]
x: [1, 2, 3]
4. map与lambda表达式结合使用
可以简化代码
x = [1, 2, 3]r = map(lambda x: x + x, x)print('结果: ', list(r))
print('x: ', x)
结果:
x = [1, 2, 3]r = map(lambda x: x * x, x)print('结果: ', list(r))
print('x: ', x)
使用多个序列, 需要注意, 后面传入的序列个数和lambda表达式参数个数一直
x = [1, 2, 3]
y = [10, 20, 30, 40]
# 传入x和y两个参数, lambda表示参数个数也是2
r = map(lambda x, y: x * y, x, y)print('结果: ', list(r))
print('x: ', x)
结果:
结果: [10, 40, 90]
x: [1, 2, 3]
返回结果的长度是最小的序列长度
5. reduce函数
from functools import reduce
recude(函数, 序列, 初值)
from functools import reducedef add(x, y):return x + yx = [1, 2, 3]
r = reduce(add, x)
print(r)
结果
6
reduce()
函数运算原理
没有初值的情况
第一次执行, 调用add(1, 2), r = add(1, 2)
第二次执行, 调用add(r, 3), r = add(r, 3)
此时, 序列已经执行到最后一个元素了, 返回执行的结果
所以结果是: add(add(1, 2), 3)
有初值的情况
第一次执行, 调用add(初值, 2), r = add(初值, 2)第二次执行, 调用add(r, 2), r = add(r, 2)
第三次执行, 调用add(r, 3), r = add(r, 3)
此时, 序列已经执行到最后一个元素了, 返回执行的结果
所以结果是: add(add(add(初值, 1), 2), 3)
from functools import reducedef add(x, y):return x + yx = ['1', '2', '3']
r = reduce(add, x, 'v')
print(r)
结果:
v123
6. filter函数
filter(函数, 序列)
例子: 保留x列表中值大于3的元素
x = [1, 2, 6, 5, 4, 3]def fun(x):return True if x > 3 else Falser = filter(fun, x)print(list(r))
装饰器
1. 引例
现在有三个函数, 在每个函数中都要输出函数调用的时间
import timedef practice():def func1():print(time.time())print('func1')def func2():print(time.time())print('func2')def func3():print(time.time())print('func3')return func1, func2, func3printTime = practice()for i in printTime:i()
结果:
1653194377.809377
func1
1653194377.809377
func2
1653194377.809377
func3
如果此时, 将打印时间改为打印函数名, 是不是需要对每一个函数进行修改?
修改是封闭的, 扩展是开放的, 修改不能解决根本
优化
import timedef practice():def printTime(func):print(time.time())func()def func1():print('func1')def func2():print('func2')def func3():print('func3')return func1, func2, func3, printTimefunc1, func2, func3, printTime = practice()printTime(func1)
printTime(func2)
printTime(func3)
结果:
1653194518.6538224
func1
1653194518.6538224
func2
1653194518.6538224
func3
为了更简便, 这就引入了装饰器
2. 装饰器
import time# 定义装饰器
def decorator(func):def wrapper():print(time.time())func()return wrapperdef func1():print('func1')# 使用装饰器
func1 = decorator(func1)
func1()
看上去, 这种使用跟printTime()
这种方法没什么区别
3. 装饰器使用
使用@
简化调用
使用方法: @装饰器名字
import timedef decorator(func):def wrapper():print(time.time())func()return wrapper@decorator
def func1():print('func1')func1()
结果
1653195433.3289523
func1
4. 对带有参数的函数定义装饰器
对于wrapper()函数
使用可变参数
import timedef decorator(func):def wrapper(*parameters):print(time.time())func(*parameters)return wrapper@decorator
def func1(x):print('func1', x)@decorator
def func2(x, y):print('func1', x, y) func1(1)
func2('aaa', 'bbb')
结果:
1653196573.0688334
func1 1
1653196573.0688334
func1 aaa bbb
这种情况也有问题, 不兼容 **args
参数
import timedef decorator(func):def wrapper(*parameters):print(time.time())func(*parameters)return wrapper@decorator
def func1(**x):print('func1', x)func1(a = 2, b = 3)
会报错
解决办法:
import timedef decorator(func):def wrapper(*parameters, **kwargs):print(time.time())func(*parameters, **kwargs)return wrapper@decorator
def func1(**x):print('func1', x)func1(a = 2, b = 3)
5. 带有参数的装饰器的理解
*parameters
用于获取函数默认的传参顺序所获得的值
**kwargs
用于获取可变参数列表的值
def decorator(func):def wrapper(*parameters, **kwargs):print(parameters)print(kwargs)func(*parameters, **kwargs)return wrapper@decorator
def func1(p1, p2, **x):print('func1', p1, p2, x)func1(1, 2, a = 2, b = 3)
结果:
(1, 2)
{'a': 2, 'b': 3}
func1 1 2 {'a': 2, 'b': 3}
6. 装饰器完整定义
def 装饰器名字(func):def wrapper(*parameters, **kwargs):所要执行的逻辑func(*parameters, **kwargs)return wrapper
使用
@装饰器名称
7. 使用python装饰器保存内置变量的值
from functools import wrapsdef 装饰器名字(func):@wraps(func)def wrapper(*parameters, **kwargs):所要执行的逻辑func(*parameters, **kwargs)return wrapper
8. 数据类装饰器 dataclass
用来简化构造函数赋值
原来的样子
class Student:def __init__(self, name, age):self.name = nameself.age = age
使用修饰器
from dataclasses import dataclass@dataclass
class Student:name: strage: int# def __init__(self, name, age):# self.name = name# self.age = agedef showInfo(self):print(self.name, self.age)student = Student('小米', 18)
student.showInfo()
看一下dataclass函数
def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False,unsafe_hash=False, frozen=False, match_args=True,kw_only=False, slots=False):...
可以看出, 在@dataclass后面可以指定参数
init=True 表示默认产生构造函数
用字典映射代替switch case
C语言中的switch case语句
switch (表达式) {case 整型数值1: 语句 1;case 整型数值2: 语句 2;......case 整型数值n: 语句 n;default: 语句 n+1;
}
python中使用字典
switcher = {值1: 函数1值2: 函数2......值n: 函数n
}r = switcher.get(值, default函数)()
例子: 输入1 ~ 7之间的数字, 输出对应的星期
def isMonday():return '星期一'def isTuesday():return '星期二'def isWednesday():return '星期三'def isThursday():return '星期四'def isFriday():return '星期五'def isSaturday():return '星期一'def isSunday():return '星期天'def default():return '输入错误'switcher = {1: isMonday,2: isTuesday,3: isWednesday,4: isThursday,5: isFriday,6: isSaturday,7: isSunday
}v = input()
r = switcher.get(int(v), default)()
print(r)
列表推导式
列表推导式: 使用列表, 字典, 元组, 集合, 创建一个新的列表, 字典, 元组, 集合
(1). 简单使用
[ 表达式 i for in x ]
def add(x):return x + xx = [1, 2, 3]b = [add(i) for i in x if i == 2]print(b)
结果:
[2, 4, 6]
(2). 带有条件的列表推导式
[ 表达式 i for in x if 表达式 ]
当i满足条件e()时, 执行f(), 将结果放入新的列表中
def add(x):return x + xdef condition(x):return x == 2x = [1, 2, 3]b = [add(i) for i in x if condition(i)]print(b)
结果:
[4]
(3). 使用列表推导式创建元组
def add(x):return x + xdef condition(x):return x >= 2x = [1, 2, 3, 4, 5]b = (add(i) for i in x if condition(i))print(b)
结果:
<generator object <genexpr> at 0x00000134B19F18C0>
此时结果不是元组, 而是一个generator, 遍历一下generator
def add(x):return x + xdef condition(x):return x >= 2x = [1, 2, 3, 4, 5]b = (add(i) for i in x if condition(i))for i in b:print(i)
结果:
4
6
8
10
转换一下可以得到元组
def add(x):return x + xdef condition(x):return x >= 2x = [1, 2, 3, 4, 5]b = tuple((add(i) for i in x if condition(i)))print(b)
结果:
(4, 6, 8, 10)
(4). 字典列表推导式
items()
students = {'张三': 18,'李四': 19,'王五': 21
}s = [key for key, value in students.items()]print(s)
结果:
['张三', '李四', '王五']
需要注意的是, 字典遍历需要使用items()
函数
字典推导字典
将students字典中的key变成value, value变成key
students = {'张三': 18,'李四': 19,'王五': 21
}s = {value: key for key, value in students.items()}print(s)
结果:
{18: '张三', 19: '李四', 21: '王五'}
函数式编程
for i in range(start, end, step = 1):pass
代替
[pass for i in range(start, end, step = 1)]
list(map(lambda i: dosomething, [i for i in range(start, end, step = 1)])
)
迭代器
(1). 可迭代对象 和 迭代器
可迭代对象: 可以使用for-in循环遍历的对象
迭代器: 是一个类, 可以被for-in循环遍历
(2). 自定义迭代器
类实现两个函数, __iter__()
和 __next__()
def __iter__(self):passdef __next__(self):pass
例子:
class BookCollection:def __init__(self):self.data = ['1', '2', '3']self.cur = 0def __iter__(self):return selfdef __next__(self):if self.cur >= len(self.data):self.cur = 0raise StopIteration()r = self.data[self.cur]self.cur += 1return rbooks = BookCollection()
[print(i) for i in books]
结果:
1
2
3
生成器
生成器是针对函数的, 保存一个算法
def generate(end):n = 0while n < end:n += 1yield nprint(generate(100))
使用列表推导式得到生成器
print(i for i in range(1, 9))
海象运算符 :=
可以使用在if中, 使得函数调用的值赋给一个变量, 同时进行条件判断操作, 省去了在外定义变量
a = "Python"if l := len(a) > 5:print(l)
结果:
6
使用前:
a = "Python"
l = len(a)
if l > 5:print(l)
Python 之 进阶 学习相关推荐
- 【数据采集】python爬虫进阶学习——聚焦爬虫(纯干货)
本篇文章涉及到数据解析方面的知识(聚焦爬虫) 在看这篇文章之前,建议读者有一定的爬虫相关的基础知识,零基础的同学请移步 半小时学会python爬虫 以下是本篇文章正文内容,建议使用PyCharm等工具 ...
- leetcode与python进阶学习总结
转自:leetcode与python进阶学习总结 l1是一个链表型,val是其属性,以下句子意义为如果l1不为空则取l1.val否则取0,节省代码空间,干净利落 x= l1.val if l1 els ...
- 36篇博文带你学完opencv :python+opencv进阶版学习笔记目录
基础版学习笔记传送门 36篇博文带你学完opencv :python3+opencv学习笔记汇总目录(基础版) 进阶版笔记 项目 opencv进阶学习笔记1: 调用摄像头用法大全(打开摄像头,打开摄像 ...
- opencv进阶学习笔记13:图像形态学操作大全(膨胀,腐蚀,开闭,黑帽,顶帽,梯度)python版
基础版学习笔记: python3+opencv学习笔记汇总目录(适合基础入门学习) 进阶版笔记目录链接: python+opencv进阶版学习笔记目录(适合有一定基础) 基础版形态学: opencv学 ...
- python进阶学习--- django框架解析 ---领悟编程语言共性与特性【后续详解】
python进阶学习---> django框架解析 --->领悟编程语言共性与特性 1.python语言介绍 python解释型脚本语言 2.python执行原理 python解释 ...
- python进阶学什么意思_Python进阶学习
学习目录阿力阿哩哩:深度学习 | 学习目录zhuanlan.zhihu.com 上一期我们讲到阿力阿哩哩:Python基础zhuanlan.zhihu.com 3.3Python进阶学习 3.3. ...
- 一个python下从入门到进阶学习人工智能的网站
转一个利用python从入门到进阶学习人工智能的网站:https://www.captainai.net/st/ 门槛低,比较通俗易懂. 先粘一下前言部分: 大家好!欢迎来到我的网站! 人工智能被认为 ...
- 阿里云天池 Python训练营Task3: Python基础进阶:从函数到高级魔法方法 学习笔记
本学习笔记为阿里云天池龙珠计划Python训练营的学习内容,学习链接为:https://tianchi.aliyun.com/specials/promotion/aicamppython?spm=5 ...
- Python数据科学学习进阶
Python菜鸟到Python Kaggler 如果你梦想成为一名数据科学家,或者已然是数据科学家的你想扩展自己的工具库,那么,你找对地方啦.本文旨在为做数据分析的Python人提供一条全方位的学习之 ...
最新文章
- 为什么那么多程序员不敢学Python?
- ROS探索总结(十三)(十四)(十五)——导航与定位框架 move_base(路径规划) amcl(导航与定位)
- matplotlib.pyplot常用画图方式函数封装(一)——.plot绘制折线图及设置坐标轴箭头完美解决
- VTK:移除外表面用法实战
- 技术详解:基于人脸识别的 AI 弹幕
- spring cloud netflix
- 《C#3.0 in a Nutshell,3rd Edition》之C#3.0和.net3.5基本介绍篇
- 学术英语视听说2听力原文_做英语听力题有哪些非常实用的小技巧?
- MySQL 按照拼音给中文字段排序
- 头像怎么画,日系头像绘画教程
- ubuntu16.04 nvidia gtx1060 驱动安装
- GB/T 28181-2011、2016、2022变更对比
- 转行Python容易吗?
- IP地址,子网掩码和网关
- Bootstrap-用ICheck插件给CheckBox换新装
- 网络时间同步(卫星时钟同步系统)技术原理介绍
- [评测]灵动半导体MM32W3蓝牙开发板开箱报告
- 错误:can‘t create 事务 lock on /var/lib/rpm/.rpm.lock (只读文件系统)
- 关于IMEI、MEID、IMSI
- 信号处理与数据分析——Z变换