文章目录
概要
由于最近在看cv领域相关代码时,有些python语法看不太懂,所以写下这篇博客来总结一下常见的python语法
`参考文档:https://blog.csdn.net/ityard/article/details/102807071?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171331273816800182723590%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=171331273816800182723590&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-2-102807071-null-null.142^v100^pc_search_result_base7&utm_term=python&spm=1018.2226.3001.4187`
1.入门知识
python解释器
Python是一门解释型语言, 使用Python语法编写的代码需要被Python解释器逐行解释执行.
Python解释器是一款应用程序, 负责解析和执行Python代码.
解释器的性能对Python程序的执行效率有很大影响.
2.基本语句
标识符:
标识符是编程时使用的名字,用于给变量、函数、语句块等命名,Python 中标识符由字母、数字、下划线组成,不能以数字开头,区分大小写。
以下划线开头的标识符有特殊含义,单下划线开头的标识符,如:_xxx
,表示不能直接访问的类属性,需通过类提供的接口进行访问,不能用 from xxx import * 导入;双下划线开头的标识符,如:__xx
,表示私有成员;双下划线开头和结尾的标识符,如:__xx__
,表示 Python 中内置标识,如:init() 表示类的构造函数。
for 循环
str = 'Python'
for s in str:
print(s)
3.字符串
访问范围内字符
s = 'Python'
# 访问 yt
print(s[1:3])
# 访问 Pyt
print(s[:3])
# 访问 hon
print(s[3:])
4.序列
Python 中的序列是一块可存放多个值的连续内存空间,所有值按一定顺序排列,每个值所在位置都有一个编号,称其为索引,我们可以通过索引访问其对应值。
索引
str = 'Python'
print('str[0] str[-6] =', str[0], str[-6])
print('str[5] str[-1] =', str[5], str[-1])
输出结果:
str[0] str[-6] = P P
str[5] str[-1] = n n
切片
切片操作可以访问一定范围内的元素,语法如下所示:
sname[start : end : step]
sname:表示序列的名称;
start:开始索引位置(**包括该位置**),默认为 0;
end:表示切片的结束索引位置(**不包括该位置**),默认为序列的长度;
step:步长。
以字符串为例,如下所示:
str = 'Python'
print(str[:3])
print(str[3:])
print(str[:])
输出结果:
Pyt
hon
Python
元素是否在序列中
Python 使用 in 关键字检查某元素是否为序列的成员,语法如下:
val in seq
val:要检查的元素;
seq:指定的序列。
通过一个例子作进一步了解,以字符串为例,如下所示:
str = 'Python'
print('on'in str)
输出结果:
True
5.列表[]与元组 ()
Python 中没有数组,而是加入了功能更强大的列表(list),列表可以存储任何类型的数据,同一个列表中的数据类型还可以不同;列表是序列结构,可以进行序列结构的基本操作:索引、切片、加、乘、检查成员。
列表
- 创建
列表中所有元素都放在一个中括号 [] 中,相邻元素之间用逗号 , 分隔,如下所示:
l = [1024, 0.5, 'Python']
- 访问
通过索引访问列表中的值,还可以使用 : 截取范围内的元素,如下所示:
l = [1024, 0.5, 'Python']
print('l[0] -->', l[0])
print('l[1:] -->', l[1:])
输出结果:
l[0] --> 1024
l[1:] --> [0.5, 'Python']
- 更新
除了对列表中现有元素进行修改外,还可以使用 append() 向列表中添加新元素,如下所示:
l = [1024, 0.5, 'Python']
修改列表中第二个元素
l[1] = 5
向列表中添加新元素
l.append('Hello')
print('l[1] -->', l[1])
print('l -->', l)
输出结果:
l[1] --> 5
l --> [1024, 5, 'Python', 'Hello']
- 删除
使用 del 删除列表中元素,如下所示:
l = [1024, 0.5, 'Python']
# 删除列表中第二个元素
del l[1]
print('l -->', l)
输出结果:
l --> [1024, 'Python']
- 常用方法
① count()
统计列表中某个元素出现的次数,使用如下所示:
l = ['d', 'b', 'a', 'f', 'd']
print("l.count('d') -->", l.count('d'))
输出结果:
l.count('d') --> 2
② index()
查找某个元素在列表中首次出现的位置(即索引),使用如下所示:
l = ['d', 'b', 'a', 'f', 'd']
print("l.index('d') -->", l.index('d'))
输出结果:
l.index('d') --> 0
③ remove()
移除列表中某个值的首次匹配项,使用如下所示:
l = ['d', 'b', 'a', 'f', 'd']
l.remove('d')
print("l -->", l)
输出结果:
l --> ['b', 'a', 'f', 'd']
④ sort()
对列表中元素进行排序,使用如下所示:
l = ['d', 'b', 'a', 'f', 'd']
l.sort()
print('l -->', l)
输出结果:
l --> ['a', 'b', 'd', 'd', 'f']
⑤ copy()
复制列表,使用如下所示:
l = ['d', 'b', 'a', 'f', 'd']
lc = l.copy()
print('lc -->', lc)
输出结果:
lc --> ['d', 'b', 'a', 'f', 'd']
元组
元组(tuple)与列表类似,但元组是不可变的,可简单将其看作是不可变的列表,元组常用于保存不可修改的内容。
- 创建
元组中所有元素都放在一个小括号 () 中,相邻元素之间用逗号 , 分隔,如下所示:
t = (1024, 0.5, 'Python')
- 访问
与访问列表中元素类似,如下所示:
t = (1024, 0.5, 'Python')
print('t[0] -->', t[0])
print('t[1:] -->', t[1:])
输出结果:
t[0] --> 1024
t[1:] --> (0.5, 'Python')
- 修改
元组中元素不能被修改,我们要用重新赋值的方式操作,如下所示:
t = (1024, 0.5, 'Python')
t = (1024, 0.5, 'Python', 'Hello')
print('t -->', t)
输出结果:
t --> (1024, 0.5, 'Python', 'Hello')
- 删除
元组中的元素不能被删除,我们只能删除整个元组,如下所示:
t = (1024, 0.5, 'Python')
del t
print('t -->', t)
输出结果:
NameError: name 't' is not defined
由于元组实例被删除,所以输出了异常信息。
- 常用方法
① len()
计算元组中元素个数,使用如下所示:
t = (1024, 0.5, 'Python')
print('len(t) -->', len(t))
输出结果:
len(t) --> 3
② max() 和 min()
返回元组中元素最大、最小值,使用如下所示:
t = ('d', 'b', 'a', 'f', 'd')
print('max(t) -->', max(t))
print('min(t) -->', min(t))
输出结果:
max(t) --> f
min(t) --> a
③ tuple()
将列表转换为元组,使用如下所示:
l = ['d', 'b', 'a', 'f', 'd']
t = tuple(l)
print('t -->', t)
输出结果:
t --> ('d', 'b', 'a', 'f', 'd')
6.字典{}与集合 {}
字典
今天我们说的字典(dict)是 Python 的数据结构,因为都叫字典,我们不用想也知道它们是十分相似的,它们的内容都是以键-值(key-value)的方式存在的。
dict 拥有良好的查询速度,dict 中的值可以是任意 Python 对象,多次对一个 key 赋 value,后面的 value 会把前面的 value 覆盖。
字典的内容在花括号 {} 内,键-值(key-value)之间用冒号 : 分隔,键值对之间用逗号 , 分隔,比如创建字典 d,如下所示:
d = {'name':'小明', 'age':'18'}
# 使用 dict 函数
# 方式一
l = [('name', '小明'), ('age', 18)]
d = dict(l)
# 方式二
d = dict(name='小明', age='18')
# 空字典
d = dict()
d = {}
字典中的值通过 key 进行访问,如下所示:
>>> d = dict(name='小明', age='18')
>>> d['name']
'小明'
# 使用 get 方法
>>> d.get('name')
'小明'
修改操作,以修改 age 为例,如下所示:
>>> d = dict(name='小明', age='18')
>>> d['age'] = '20'
>>> d['age']
'20'
清空集合,如下所示:
>>> d = dict(name='小明', age='18')
>>> d.clear()
>>> d
{}
获取字典的长度,如下所示:
>>> d = dict(name='小明', age='18')
>>> len(d)
2
集合
集合(set)与字典相同均存储 key,但也只存储 key,因 key 不可重复,所以 set 的中的值不可重复,也是无序的。
集合使用花括号 {} 或者 set() 函数创建,如果创建空集合只能使用 set() 函数,以创建集合 s 为例,如下所示:
s = {'a', 'b', 'c'}
# 使用 set 函数
s = set(['a', 'b', 'c'])
# 空集合
s = set()
集合中重复的元素会被自动过滤掉,如下所示:
>>> s = {'a', 'a', 'b', 'c', 'c'}
>>> s
{'a', 'c', 'b'}
添加元素可以使用 add 或 update 方法,如果元素已经存在,则不进行操作,如下所示:
>>> s = {'a', 'b', 'c'}
>>> s.add('d')
>>> s
{'a', 'd', 'c', 'b'}
>>> s.update('e')
>>> s
{'a', 'b', 'e', 'd', 'c'}
# 添加已经存在的元素 a
>>> s.add('a')
>>> s
{'a', 'b', 'e', 'd', 'c'}
删除元素使用 remove 方法,如下所示:
>>> s = {'a', 'b', 'c'}
>>> s.remove('c')
>>> s
{'a', 'b'}
清空集合使用 clear 方法,如下所示:
>>> s = {'a', 'b', 'c'}
>>> s.clear()
>>> s
set()
获取集合的长度,同样使用 len 方法,如下所示:
>>> s = {'a', 'b', 'c'}
>>> len(s)
3
7.与时间相关的模块
time 模块
time 模块提供了很多与时间相关的类和函数,下面我们介绍一些常用的。
datetime 模块
datatime 模块重新封装了 time 模块,提供了更多接口,变得更加直观和易于调用。
calendar 模块
calendar 模块提供了很多可以处理日历的函数。
8.函数
自定义函数
Python 使用 def 关键字来声明函数,格式如下所示:
def 函数名(参数):
函数体
return 返回值
如果要定义一个无任何功能的空函数,函数体只写 pass 即可。格式如下所示:
def 函数名():
pass
当我们不确定参数的个数时,可以使用不定长参数,在参数名前加 * 进行声明,格式如下所示:
def 函数名(*参数名):
函数体
我们还可以使用 lambda 定义匿名函数,格式如下所示:
lambda 参数 : 表达式
函数调用
调用一个函数只需要知道函数名和参数即可。
9.模块与包
模块
Python 中一个以 .py 结尾的文件就是一个模块,模块中定义了变量、函数等来实现一些类似的功能。Python 有很多自带的模块(标准库)和第三方模块,一个模块可以被其他模块引用,实现了代码的复用性。
包
包是存放模块的文件夹,包中包含 __init__.py
和其他模块,__init__.py
可为空也可定义属性和方法,在 Python3.3 之前的版本,一个文件夹中只有包含 __init__.py
,其他程序才能从该文件夹引入相应的模块、函数等,之后的版本没有 __init__.py
也能正常导入,简单来说就是 Python3.3 之前的版本,__init__.py
是包的标识,是必须要有的,之后的版本可以没有。
引用
从包中引入模块有如下两种方式:
import …
import 包名1.包名2...模块名
from … import …
from 包名1.包名2... import 模块名
from 包名1.包名2...模块名 import 变量名/函数名
下面我们使用创建好的包和模块演示一下,如下所示:
# a 模块中引入 b 模块
import pg1.b
from pg1 import b
# a 模块中引入 c 模块
import pg2.c
from pg2 import c
# a 模块中引入 c 模块和 d 模块
import pg2.c,pg2.d
from pg2 import c,d
# a 模块中引入包 pg2 下的所有模块
from pg2 import *
# a 模块中引入 d 模块中函数 d()
from pg2.d import d
# 调用函数 d()
d()
10. 面向对象
面向对象(OOP)是一种对现实世界理解和抽象的方法,对象的含义是指在现实生活中能够看得见摸得着的具体事物,一句比较经典的描述是一切皆对象,Python 是一门面向对象的语言,面向对象编程简单来说就是一种封装代码的方式。
-
面向对象相关概念
类:描述具有相同属性和方法的集合,简单来说就是一个模板,通它来创建对象。 对象:类的实例。 方法:类中定义的函数。 类变量:定义在类中且在函数之外的变量,在所有实例化对象中公用。 局部变量:方法中定义的变量,只作用于当前实例。
基本操作
比如我们定义一个类 Cat,如下所示:
class Cat:
# 属性
color = 'black'
# 构造方法
def __init__(self, name):
self.name = name
# 自定义方法
def eat(self, food):
self.food = food
print(self.name, '正在吃'+food)
构造方法 init() 会在类实例化时自动调用。无论构造方法还是其他方法都需要将 self 作为第一个参数,它代表类的实例。
类创建好后,我们可以直接通过类名访问属性,格式为:类名.属性名,比如我们访问 Cat 类的 color 属性,如下所示:
print('color-->', Cat.color)
上面 Cat 类中定义的属性和方法都是公开的,除此之外我们还可以定义私有属性和方法,声明方式为:在属性名或方法名前加两条下划线,示例如下所示:
class Cat:
__cid = '1'
def __run(self):
pass
需要强调一点是:外部不能访问私有属性和调用私有方法,自然 Cat.__cid 是会报错的。
创建对象也称类的实例化,比如我们通过 Cat 类创建对象,如下所示:
# 创建对象
c = Cat('Tom')
创建好对象后,我们就可以使用它访问属性和调用方法了,如下所示:
# 访问属性
print('name-->', c.name)
print('color-->', c.color)
# 调用方法
c.eat('鱼')
同样对象 c 不能访问私有属性 __cid 及调用私有方法 __run,那我们会有这样一个疑问,这个私有属性和方法难道定义了却不能用吗?
来一起看个例子,如下所示:
class Cat:
__cid = '1'
def __run(self, speed):
print('__cid是'+self.__cid+'的猫', '以'+speed+'的速度奔跑')
def run(self, speed):
self.__run(speed)
c.run('50迈')
输出结果:
__cid是1的猫 以50迈的速度奔跑
通过示例我们可以看出,在内部私有属性和方法是可以被访问和调用的。
内置方法
继承
Python 支持类的继承,而且支持多继承,语法格式为:
class 基类(子类1, 子类2 ...):
...
示例如下所示:
# 波斯猫类
class PersianCat(Cat):
def __init__(self, name):
self.name = name
def eat(self, food):
print(self.name, '正在吃'+food)
#加菲猫类
class GarfieldCat(Cat):
def __init__(self, name):
self.name = name
def run(self, speed):
print(self.name, '正在以'+speed+'的速度奔跑')
# 单继承
class SingleCat(PersianCat):
pass
# 多继承
class MultiCat(PersianCat, GarfieldCat):
pass
#调用
sc = SingleCat('波斯猫1号')
sc.eat('鱼')
mc = MultiCat('波斯加菲猫1号')
mc.eat('鱼')
mc.run('50迈')
如果继承的父类方法不能满足我们的需求,这时子类可以重写父类方法,如下所示:
class SingleCat(PersianCat):
def eat(self, food ):
print(self.name, '正在吃'+food, '十分钟后', self.name+'吃饱了')
sc = SingleCat('波斯猫1号')
sc.eat('鱼')
调用父类同名成员
一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员,如果需要使用被复写的父类的成员,需要特殊的调用方式:
方式1:
调用父类成员
使用成员变量:父类名.成员变量
使用成员方法:父类名.成员方法(self)
方式2:
使用super()调用父类成员
使用成员变量:super().成员变量
使用成员方法:super().成员方法()
12. os模块
我们都知道 os 中文就是操作系统的意思,顾名思义,Python 的 os 模块提供了各种操作系统的接口,这些接口主要是用来操作文件和目录。
Python 中所有依赖于操作系统的内置模块统一设计方式为:对于不同操作系统可用的相同功能使用相同的接口,这样大大增加了代码的可移植性;当然,通过 os 模块操作某一系统的扩展功能也是可以的,但这样做会损害代码的可移植性。
- os.getcwd()
查看当前路径。
import os
print(os.getcwd())
- os.listdir(path)
返回指定目录下包含的文件和目录名列表。
import os
print(os.listdir('E:/'))
- os.path.abspath(path)
返回路径 path 的绝对路径。
import os
# 当前路径(相对路径方式)
print(os.path.abspath('.'))
- os.path.split(path)
将路径 path 拆分为目录和文件两部分,返回结果为元组类型。
import os
print(os.path.split('E:/tmp.txt'))
- os.path.join(path, *paths)
将一个或多个 path(文件或目录) 进行拼接。
import os
print(os.path.join('E:/', 'tmp.txt'))
- os.path.getctime(path)
返回 path(文件或目录) 在系统中的创建时间。
import os
import datetime
print(datetime.datetime.utcfromtimestamp(os.path.getctime('E:/tmp.txt')))
12. 文件的基本操作
13.错误和异常
14.枚举
什么是枚举?
枚举可看作是一系列符号名称的集合,集合中每一个元素要保证唯一性和不可变,因此我们可以对枚举中元素进行恒等比较,通俗来讲枚举就是一系列常量的集合,枚举是可迭代的。
枚举有什么作用?
我们先来思考一个问题:不使用枚举我们如何定义常量呢?
常用的做法是采用变量名大写的方式来定义,这种方式虽然简单,但问题在于我们定义的仍然是变量、是可以被修改的,而常量是什么呢?简单来说就是不可变的量,枚举就有不可变的特性,所以枚举的主要作用就是用来定义常量的。
15.迭代器与生成器
迭代
我们知道 Python 中有一些对象可以通过 for 来循环遍历,比如:列表、元组、字符等,以字符串为例,如下所示:
for i in 'Hello':
print(i)
执行结果:
H
e
l
l
o
这个遍历过程就是迭代。
可迭代对象
可迭代对象需具有 __iter__()
方法,它们均可使用 for 循环遍历,我们可以使用 isinstance()
方法来判断一个对象是否为可迭代对象,看下示例:
from collections import Iterable
print(isinstance('abc', Iterable))
print(isinstance({1, 2, 3}, Iterable))
print(isinstance(1024, Iterable))
执行结果:
True
True
False
迭代器
迭代器需要具有 iter() 和 next() 两个方法,这两个方法共同组成了迭代器协议,通俗来讲迭代器就是一个可以记住遍历位置的对象,迭代器一定是可迭代的,反之不成立。
- iter():返回迭代器对象本身
- next():返回下一项数据
迭代器对象本质是一个数据流,它通过不断调用 __next__()
方法或被内置的 next() 方法调用返回下一项数据,当没有下一项数据时抛出 StopIteration 异常迭代结束。上面我们说的 for 循环语句的实现便是利用了迭代器。
我们试着自己来实现一个迭代器,如下所示:
class MyIterator:
def __init__(self):
self.s = '程序之间'
self.i = 0
def __iter__(self):
return self
def __next__(self):
if self.i < 4:
n = self.s[self.i]
self.i += 1
return n
else:
raise StopIteration
mi = iter(MyIterator())
for i in mi:
print(i)
输出结果:
程
序
之
间
生成器
生成器是用来创建迭代器的工具,其写法与标准函数类似,不同之处在于返回时使用 yield 语句
yield 是一个关键字,作用和 return 差不多,差别在于 yield 返回的是一个生成器(在 Python 中,一
边循环一边计算的机制,称为生成器),它的作用是:有利于减小服务器资源,在列表中所有数据存
入内存,而生成器相当于一种方法而不是具体的信息,用多少取多少,占用内存小。
生成器的创建方式有很多种,比如:使用 yield 语句、生成器表达式(可以简单的理解为是将列表的 [] 换成了 (),特点是更加简洁,但不够灵活)。看下示例:
def reverse(data):
for i in range(len(data)-1, -1, -1):
yield data[i]
for char in reverse('Hello'):
print(char)
执行结果:
o
l
l
e
H
16.装饰器
17. 命名空间 & 作用域
18. 数学相关模块
19. sys模块
sys 模块主要负责与 Python 解释器进行交互,该模块提供了一系列用于控制 Python 运行环境的函数和变量。
之前我们说过 os 模块,该模块与 sys 模块从名称上看着好像有点类似,实际上它们之间是没有什么关系的,os 模块主要负责与操作系统进行交互。
20. argparse 模块
argparse 模块主要用于处理 Python 命令行参数和选项,程序定义好所需参数后,该模块会通过 sys.argv
解析出那些参数;除此之外,argparse 模块还会自动生成帮助和使用手册,并在用户给程序传入无效参数时报出错误信息。使用 argparse 模块,我们可以轻松的编写出用户友好的命令行接口。
21. 正则表达式
正则表达式是一个强大的字符串处理工具,几乎所有的字符串操作都可以通过正则表达式来完成,其本质是一个特殊的字符序列,可以方便的检查一个字符串是否与我们定义的字符序列的某种模式相匹配。
正则表达式并不是 Python 所特有的,几乎所有编程语言都支持正则表达式,Python 提供了内置模块 re
和第三方模块regex
来支持正则表达式,regex
模块提供了与re
模块兼容的 API 接口,同时还提供了额外的功能和更全面的 Unicode 支持,本文只介绍re
模块。
22.json数据格式
什么是json
JSON是一种轻量级的数据交互格式。可以按照JSON指定的格式去组织和封装数据
JSON本质上是一个带有特定格式的字符串
主要功能:json就是一种在各个编程语言中流通的数据格式,负责不同编程语言中的数据传递和交互. 类似于:
国际通用语言-英语
中国56个民族不同地区的通用语言-普通话
json有什么用
各种编程语言存储数据的容器不尽相同,在Python中有字典dict这样的数据类型, 而其它语言可能没有对应的
字典。为了让不同的语言都能够相互通用的互相传递数据,JSON就是一种非常良好的中转数据格式。如下图,
以Python和C语言互传数据为例:
23.XML
XML(Extensible Markup Language)中文译为可扩展标记语言,它是一种简单、灵活、易扩展的文本格式,它主要关注数据内容,常用来传送、存储数据。