Python查缺补漏
Python (with matlab)
安装用于 Python 的 MATLAB Engine API - MATLAB & Simulink - MathWorks 中国
- 要从 MATLAB 文件夹安装,请在 Windows® 上键入:
cd "_matlabroot_\extern\engines\python"
python -m pip install .
- 使用以下命令从 https://pypi.org/project/matlabengine 安装引擎 API:
python -m pip install matlabengine
启动 MATLAB Engine
启动 Python。在 Python 提示符下键入以下命令,以导入 MATLAB 模块并启动引擎:
1 | import matlab.engine |
matlab2023 最低python版本为 3.9
matlab2019 最高python版本为 3.7
Project
Project introduction | Link |
---|---|
许多 Linux 发行版都用 systemd 来管理系统的服务,比如开机启动、自动重启、守护进程等。该项目讲解了如何入门 systemd,并提供了一个 Python 脚本和 systemd unit 文件,可以在此基础上快速开发出 systemd 服务。 | torfsen/python-systemd-tutorial: A tutorial for writing a systemd service in Python |
基于 OpenCV 的拼接模块开发的用于快速拼接图片的 Python 库 | OpenStitching/stitching: A Python package for fast and robust Image Stitching |
手写实现李航《统计学习方法》书中全部算法 | Dod-o/Statistical-Learning-Method_Code: 手写实现李航《统计学习方法》书中全部算法 |
使用 Python 和 Matplotlib 进行科学可视化的开源书籍 | rougier/scientific-visualization-book: An open access book on scientific visualization using python and matplotlib |
Python 写的人脸识别和面部属性分析框架,可根据人脸图像智能识别年龄、性别、情绪等信息 | serengil/deepface: A Lightweight Face Recognition and Facial Attribute Analysis (Age, Gender, Emotion and Race) Library for Python |
积累编写技巧
元组索引列表
1 | def topk_freq(self, x_freq): |
- 变量的交换
a,b = b,a
- 字符串格式化
print("Hi, I'm %s . I'm from %s . And I'm %d" % (name,country,age))
print("Hi, I'm {} . I'm from {} . And I'm {}".format(name,country,age))
print(f"Hi, I'm {name} . I'm from {country} . And I'm {age+1}"
[双字] {Python}中5个好用的<字符串格式化>技巧_哔哩哔哩_bilibili
1 | n: int = 1000000000 |
Yield
yield不需要整个列表生成完毕后再输出,可以一个一个输出。每当一个数据生成时,可以直接输出
1 | def fibonacci(n): |
map和zip
map(function,sequence)
对序列sequence中每个元素都执行函数function操作,如map(str,mylist)
:将列表中的每一项转换成字符串。
list()将每一项转换成列表
zip(*list)
返回的是一个元组,转置1
2
3
4
5
6
7
8
9
10
11
12
13
14list = [[1,2,3],[4,5,6],[7,8,9]]
t = zip(*list)
print t
# output
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
x = [1,2,3,4,5]
y = [6,7,8,9,10]
a = zip(x,y)
print a
# output
[(1, 6), (2, 7), (3, 8), (4, 9), (5, 10)]
eg:将多个列表合并创建json数组
new_list = list(map(list, zip(address, temp)))
jsonify({
‘data’: new_list
})
partial
1 | from functools import partial |
Python基础
try…except
1 | #python 异常处理 |
单个 try-except 语句捕获所有发生的异常,不是一个很好的方式。可以使用多个except异常语句
- finally 退出try时总会执行
1
2
3
4
5try:
<语句>
finally:
<语句> #退出try时总会执行
raise
1 | try: |
用户自定义异常
- 通过创建一个新的异常类,程序可以命名它们自己的异常。异常应该是典型的继承自 Exception 类,通过直接或间接的方式
- 以下为与 RuntimeError 相关的实例,实例中创建了一个类,基类为 RuntimeError,用于在异常触发时输出更多的信息
- 在 try 语句块中,用户自定义的异常后执行 except 块语句,变量 e 是用于创建 Networkerror 类的实例
1 | class Networkerror(RuntimeError): |
- 在你定义以上类后,你可以触发该异常,如下所示:
1 | try: |
异常名称 | 描述 |
---|---|
BaseException | 所有异常的基类 |
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
Exception | 常规错误的基类 |
StopIteration | 迭代器没有更多的值 |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
AssertionError | 断言语句失败 |
AttributeError | 对象没有这个属性 |
EOFError | 没有内建输入,到达 EOF 标记 |
EnvironmentError | 操作系统错误的基类 |
IOError | 输入/输出操作失败 |
OSError | 操作系统错误 |
WindowsError | 系统调用失败 |
ImportError | 导入模块/对象失败 |
LookupError | 无效数据查询的基类 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
MemoryError | 内存溢出错误(对于 Python 解释器不是致命的) |
NameError | 未声明/初始化对象 (没有属性) |
UnboundLocalError | 访问未初始化的本地变量 |
ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 一般的运行时错误 |
NotImplementedError | 尚未实现的方法 |
SyntaxError Python | 语法错误 |
IndentationError | 缩进错误 |
TabError Tab | 和空格混用 |
SystemError | 一般的解释器系统错误 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数 |
UnicodeError Unicode | 相关的错误 |
UnicodeDecodeError Unicode | 解码时的错误 |
UnicodeEncodeError Unicode | 编码时错误 |
UnicodeTranslateError Unicode | 转换时错误 |
Warning | 警告的基类 |
DeprecationWarning | 关于被弃用的特征的警告 |
FutureWarning | 关于构造将来语义会有改变的警告 |
OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
SyntaxWarning | 可疑的语法的警告 |
UserWarning | 用户代码生成的警告 |
参考教程
加减乘除
python 保留小数位
保留两位小数 a=2.32424
round(a,2)
"%.2f" %a
f'{a:.2f}'
除法和取模
Python中
// :地板除,即向负无穷取整
- 8//3 结果为2
- -8//3 结果为-3
Python中:% 取模(modulus)与取余数有很大区别
- -10%3 结果为2
- -90%8结果为6
C++中:% 取余
- -10%3 结果为-1
- -90%8结果为-2
1 | # 取模,Python中可直接用%,计算模,r = a % b |
字符串操作
str.split()
对字符串进行切片—返回一个列表- 语法
str.split(str="", num=string.count(str)).
- str:分隔符,默认为所有的空字符,包括空格、换行、指标
- num:分割次数,默认为-1,即分割所有
- 语法
str.find()
检测字符串中是否包含子字符串 str- _如果包含子字符串返回开始的索引值,否则返回-1_
- 语法
str.find(str, beg=0, end=len(string))
- str — 指定检索的字符串
- beg — 开始索引,默认为 0
- end — 结束索引,默认为字符串的长度
string.join()
- 语法
'sep'.join(seq)
以 sep 作为分隔符,将 seq 所有的元素合并成一个新的字符串 返回值:返回一个以分隔符 sep 连接各个元素后生成的字符串- sep:分隔符。可以为空
- seq:要连接的元素序列、字符串、元组、字典
- 语法
- ord() & chr()
- ord()将字符转化为ascii码
- chr()将ascii码转化为字母或实际数字
文件操作
txt文件
1 | fd = open('file.txt','w',encoding='utf-8') #utf-8 or GBK |
其中 content 可以是字符串,变量,\t ……
r | w | a |
---|---|---|
只读 | 覆盖写 | 添加写 |
读取txt行
1 | f.readlines()# 全部读取最后返回一个列表存所有的类,每行后面都会带有“\n” |
csv文件
写入列表
- headers :表头
- rows :内容
f*csv = csv.writer(f) \_f 为 open('file.txt','w',encoding='utf-8')*
- f_csv.writerow(headers)
- f_csv.writerows(rows)
1 | import csv |
_注意:如果打开 csv 文件出现空行的情况,那么需要添加一个参数 newline=”_with open('test.csv','w',newline='')as f:
class | name | sex | height | year |
---|---|---|---|---|
1 | xiaoming | male | 168 | 23 |
1 | xiaohong | female | 162 | 22 |
2 | xiaozhang | female | 163 | 21 |
2 | xiaoli | male | 158 | 21 |
写入字典
- headers :表头
- rows :内容
- f_csv = DictWriter(f,headers)
- f_csv.writeheader()
- f_csv.writerows(rows)
1 | import csv |
class | name | sex | height | year |
---|---|---|---|---|
1 | xiaoming | male | 168 | 23 |
1 | xiaohong | female | 162 | 22 |
2 | xiaozhang | female | 163 | 21 |
2 | xiaoli | male | 158 | 21 |
# csv读取
1 | import csv |
参考网站
- with open () as 读写文件
1 | # 读文件 |
参考网站
os文件夹
1 | import os |
- 删除文件:
os.remove(path)
- 获取绝对路径:
os.path.abspath
- 路径拼接:
os.path.join()
1 | print(os.path.abspath('.')) |
概念
collections 作为 Python 的内建集合模块,实现了许多十分高效的特殊容器数据类型,即除了 Python 通用内置容器: dict、list、set 和 tuple 等的替代方案
装饰器
eg:
1 | import time |
1 | def log(func): |
把@log
放到now()
函数的定义处,相当于执行了语句:
1 | now = log(now) |
由于log()是一个decorator,返回一个函数,所以,原来的now()函数仍然存在,只是现在同名的now变量指向了新的函数,于是调用now()将执行新函数,即在log()函数中返回的wrapper()函数。
装饰器需要参数
如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,写出来会更复杂。比如,要自定义log的文本:
1 | def log(text): |
这个3层嵌套的decorator用法如下:
1 | @log('execute') |
执行结果如下:
1 | >>> now() |
和两层嵌套的decorator相比,3层嵌套的效果是这样的:
1 | >>> now = log('execute')(now) |
原始函数属性复制到装饰后的函数中
以上两种decorator的定义都没有问题,但还差最后一步。因为我们讲了函数也是对象,它有__name__
等属性,但你去看经过decorator装饰之后的函数,它们的__name__
已经从原来的'now'
变成了'wrapper'
:
1 | >>> now.__name__ |
因为返回的那个wrapper()
函数名字就是'wrapper'
,所以,需要把原始函数的__name__
等属性复制到wrapper()
函数中,否则,有些依赖函数签名的代码执行就会出错。
不需要编写wrapper.__name__ = func.__name__
这样的代码,Python内置的functools.wraps
就是干这个事的,所以,一个完整的decorator的写法如下:
1 | import functools |
或者针对带参数的decorator:
1 | import functools |
import functools
是导入functools
模块。模块的概念稍候讲解。现在,只需记住在定义wrapper()
的前面加上@functools.wraps(func)
即可。
类的定义和实例创建
1 | # 定义类,类名为Cname |
类中的实例属性与类属性
- 实例属性:用于区分不同的实例,不同的类有不同的实例属性
- 类属性:是每个实例共有的属性,每个实例共有的属性
实例属性,每个实例有各自的属性
1 | # 实例属性(复杂) |
类的属性绑定后,所有实例都可以访问,而且实例访问的类属性都相同
1 | class Cname(object): |
要修改类属性,不要再实例上修改,而是在类名上修改
类的实例方法
1 | class Cname(object): |
printname(self)
就是一个最简单的方法
类中的访问限制
属性的访问限制
python的类中的属性,如果有些属性不希望被外部访问,我们可以属性命名时以双下划线开头 __
,如 __age
但,如果一个属性以”__xxx__“的形式定义,那么它可以被外部访问。以”__xxx__“定义的属性在Python的类中被称为特殊属性,有很多预定义的特殊属性是以“__xxx__”定义,所以我们不要把普通属性用”__xxx__“定义。
加双下划线__xx 的属性,可以通过“ _类名__xx ”可以访问到属性的值 如
Cname._Cname__age
方法的访问限制
双下划线,如def __printage():
- 此时,该方法只能在类的内部使用,而无法被外部调用
单下划线,不能通过 from module import * 这种方式导入,可以通过其他方式:
- import A
b = A._B()
类中的装饰方法
@classmethod
用来修饰类方法。使用在与类进行交互,但不和其实例进行交互的函数方法上@staticmethod
用来修饰静态方法。使用在有些与类相关函数,但不使用该类或该类的实例。如更改环境变量、修改其他类的属性等
classmethod必须使用类的对象作为第一个参数,而staticmethod则可以不传递任何参数
@classmethod 修饰方法——类方法
类方法,我们不用通过实例化类就能访问的方法。而且@classmethod 装饰的方法不能使用实例属性,只能是类属性。它主要使用在和类进行交互,但不和其实例进行交互的函数方法上。
1 | class Cname(object): |
printwe(cls)中cls表示的是类,它和self类实例有一定的差别。类方法中都是使用cls,实例方法中使用self
@staticmethod 修饰方法——静态方法
@staticmethod
不强制要求传递参数(它做的事与类方法或实例方法一样)@staticmethod
使用在有些和类相关函数,但不使用该类或者该类的实例。如更改环境变量、修改其他类的属性等@staticmethod
修饰的方法是放在类外的函数,我们为了方便将他移动到了类里面,它对类的运行无影响
1 | class Date(object): |
is_date_valid(date_as_string) 只有一个参数,它的运行不会影响类的属性
@staticmethod修饰方法 is_date_valid(date_as_string)中无实例化参数self或者cls;而@classmethod修饰的方法中有from_string(cls, date_as_string) 类参数cls
python中的property的使用
property的作用
- 作为装饰器 @property将类方法转换为类属性(只读)
- property重新实现一个属性的setter和getter方法
@property将类方法转换为只读属性
经常使用,将类的属性设置为不可修改
将一个类方法转变成一个类属性
1 | class Circle(object): |
创建实例后我们可以使用circle1.pi 自己获取方法的返回值,而且他只能读不能修改
property重新实现setter和getter方法
1 | class Circle(object): |
当我们以这种方式使用属性函数时,它允许pi属性设置并获取值本身而不破坏原有代码
1 | class Circle(object): |
把一个getter方法变成属性,只需要加上@property就可以了,如上此时pi(self)方法,@property本身又创建了另一个装饰器@pi.setter,负责把一个setter方法变成属性赋值,于是,将@pi.setter加到pi(self, pi)上,我们就拥有一个可控的属性操作
类的继承
类的继承
1 | class Animal(object): # python3中所有类都可以继承于object基类 |
类的继承一般都是object,然后如果想要继承自己的类,则可以把object继承对象改一下,原来类名后括号里的东西是继承对象
一定要用 super(Cat, self).__init__(name,age)
去初始化父类,否则,继承自 Animal的 Cat子类将没有 name
和 age
两个属性
函数super(Cat, self)
将返回当前类继承的父类,即 Animal,然后调用__init__()
方法,注意self参数已在super()
中传入,在__init__()
中将隐式传递,不能再写出self
Python对子类方法的重构
子类中的方法要求跟父类中的方法不同时,可以在子类中重构方法
1 | class Cat(Animal): |
当我们在子类中重构父类的方法后,Cat子类的实例先会在自己的类Cat中查找该方法,当找不到该方法时才会去父类Animal中查找对应的方法
Python中子类与父类的关系
1 | class Animal(object): |
- “A”是Animal类的实例,但,“A”不是Cat类的实例。
- “C”是Animal类的实例,“C”也是Cat类的实例。
函数 isinstance(变量,类型)
判断变量的类型,判断对象之间的关系
1 | print('"A" IS Animal?', isinstance(A, Animal)) |
python中多态
类具有继承关系,并且子类类型可以向上转型看做父类类型,如果我们从 Animal派生出 Cat和Dog,并都写了一个 call() 方法
1 | class Animal(object): |
我们定义一个do函数,接收一个变量 ‘all’,如下:
1 | def do(all): |
这种行为称为多态。也就是说,方法调用将作用在 all 的实际类型上。C 是 Cat 类型,它实际上拥有自己的 call() 方法以及从 Animal 继承的 call 方法
而调用 C .call() 总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止
注意事项
- 在继承中基类的构造方法(
__init__()方法
)不会被自动调用,它需要在其派生类的构造方法中亲自专门调用。- 在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。而在类中调用普通函数时并不需要带上self参数
- Python总是首先查找对应类的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)
类的实例可调用
可以模糊对象和函数的关系
1 | def __init__(self,name): |