数据类型:
数字类型(int、float、bool(True or False)、complex)
字符串(str) —— ' ' or " "
相关操作:通过下标获取内容,对字符串进行多步操作前一般需要进行切片[:],保证原字符串不会随着操作变化。(注意:起始坐标和结束坐标都看省略,步进根据自己的需要与否决定是否设置,有时候很简单的解决某些问题)
常用方法:
capitalize | 使指定字符串首字母大写 |
---|---|
center(width, fillchar) | 将原字符串变成指定的长度并且内容居中,剩下的部分使用指定的字符填充 |
rjust(width, fillchar) | 将原字符串变成指定的长度并且内容右对齐,剩下的部分使用指定的字符填充 |
字符串1.join(字符串2) | 在字符串2中的每个字符之间插入一个字符串1 |
列表(list)—— [1,2,3]
相关操作:列表的操作与字符串的操作基本相同,不过需要注意的是字符串的操作对象是单个字符,列表的操作对象是列表中的元素。
常用方法:
append | 在列表的末尾添加一个元素 |
---|---|
insert(下标,元素) | 在列表的指定的下标前插入一个元素(下标可以越界,如果越界,就会插入到列表的最前面或者最后面) |
+ | 列表拼接 |
del 列表[下标] | 删除列表中指定下标的元素 |
列表.remove(元素) | 删除列表中的指定的元素(如果同一个元素有多个,只删除最前面的那一个) |
列表.pop(下标) | 将列表中指定下标的元素取出来(若无坐标参数,则默认取列表中最后一个元素) |
字典(dict)—— {key:value}
相关操作:键理论上可以是任何不可变的数据类型,但实际开发的时候一般使用字符串作为key。(保证key的唯一性——同一字典中)字典获取元素的值是通过key来获取的,遍历字典一般只遍历key值,类似于列表遍历下标。字典[key]与字典.get(key)的区别:如果key不存在,前者报错,后者返回None。字典添加修改:通过key获取字典元素后赋值——当key本身就存在的时候,就是修改元素的值;不存在的时候就是给字典添加键值对。del 与 pop 类似于list中的操作,只是把下标替换为key。无法使用remove方法。
常用方法:
dict.keys() | 获取所有的key值 |
---|---|
dict.values() | 获取字典所有的值 |
dict.items() | 将字典中所有的键值对转换成一个一个的元组,key作为元组的第一个元素;value作为元组的第二个元素 |
dict.formkeys(序列,值) | 创建一个新的字典,序列中的元素作为key,value作为值 |
dict1.updata(dict2) | 使用dict2中的键值对对dict1进行更新操作。其中,如果不存在就添加;存在就更新。 |
元组(tuple)——(1,2,3)注意:元组中的不可改变
元组就是不可变的列表,列表中除了可变的操作,其他的操作都适用于元组。
元组中特有的查找方法:
first, *midel, last = names # 通过变量名前加*可以把变量名变成列表,获取多个元素
集合(set) —— {,} 空集合的表示(与字典区分) 只能全部遍历 无法精确查找 可做数学上的集合运算(判断是否包含,求交集、并集、差集、补集) 唯一(值不能重复)
一些操作:
set.add(element)
set.updata(element)
set.remove(element)
set.pop
一些运算:
求并集:|
求交集:&
差集:-
补集:^
clear:清空集合
None
(代表数据类型的英文缩写经常在类型的强制装换中用到)
python中三目运算符
值1 if 表达式 else 值2 ---> 判断表达式是否为True,为True整个表达式的结果是值1,否则是值2
运算符优先级
赋值运算符 < 逻辑运算符 < 比较运算符 < 位运算符 < 算术运算符
算数运算符中: 幂>乘除取整取余>加减
添加括号改变运算优先级,括号内的运算符依然遵从上述运算顺序
小知识
bin 二进制 oct 八进制 hex 十六进制
转义字符 \
阻止转义 r or R(多用于正则表达式)
ord 获取字符Unicode编码值 chr 得到Unicode编码值对应的字符
len 获取对象长度 (常用于判断对象或对象容器是否非空)
isinstance(值,类型名) 判断指定的值是否是指定的类型,如果是结果是True,否则结果是False。
编程类别:
面向过程编程:一步一步的写代码实现功能 -->工具:逻辑和算法
函数式编程:面对问题考虑有没有拥有某种功能的函数 -->工具:函数
面向对象编程:面对问题考虑有没有相应的对象来解决这个问题 -->工具:类和对象
Python内存管理原理
内存中的两个特殊区域:
栈:栈中的内存系统自动管理(内存的开辟和内存的释放) --- 作用域结束,内存就释放
堆:堆中的内存都需要写程序去开辟和释放的(Python中这个过程也已经自动化了)
原理:堆中的数据到底是什么时候释放的?
看一个值有几个引用,当一个值没有引用的时候,对象对应的内存空间就会被释放
(引用计数机制)
0+1-1
引用:存储对象地址的变量
封装:
对一个功能的封装 --> 函数
对多个功能的封装 --> 模块or类
对多个数据进行封装 --> 类or字典
对多个类进行封装 --> 模块
对多个模块进行封装 --> 包(文件夹)
循环
if 语句(多与循环一起使用,且多用于对循环体的判断)
if 条件语句:
语句块1
else:
语句块2
执行过程:先判断条件语句是否为True,如果为True就执行语句块1,否则执行语句块2(elif 同理)
for 循环
for 变量名 in 序列:
循环体
执行过程:使用变量去序列中取数据,一个一个的取,取完为止。每取一个值,执行一次循环体。
(range(m,n,step):从m开始,每次加step产生下一个数字,直到n前面那一个为止)
while 循环
while 条件语句:
循环体
其他语句
执行过程:判断条件语句是否为True,如果为True就执行循环体。执行完循环体,再判断条件语句是否为True,如果为True就再执行循环体....直到条件语句的值为False,循环结束,直接执行while循环后面的语句。
break和continue
均作用于循环域中,用来结束循环。continue: 结束当次循环,直接进入下次循环的判断;break:直接结束整个循环。直接执行循环后边的其他语句。
for和while的选择
for循环的循环次数是确定的,white循环的循环次数可以不确定
1.循环次数不确定的时候,选择while循环。次数确定一般使用for循环
2.通过循环遍历一个序列中的值,使用for循环
函数
函数:对实现某一特定功能的代码块的封装。
def functionName(parameter list):
'''函数说明'''
function body
声明函数的步骤:
a.确定函数功能
b.确定函数名
c.确定参数: {需不需要参数-->需要几个参数(看实现函数的功能需不需要从外面传数据到函数中)}
d.确定函数体:
e.实现函数功能
f.确定返回值
函数的调用过程:
a.先回到函数调用的位置
b.先用实参给形参赋值(传参)
c.执行函数体
d.执行完函数体,将返回值返回给函数调用表达式
e.回到函数调用的位置
参数
作用:从函数的外面给函数传值
位置参数、关键字参数、不确定个数参数
参数的默认值(有默认值可不传参)
作用域
一个变量可以使用的范围,就是这个变量的作用域(函数和类可以影响变量的作用域)
全局变量、局部变量
global:在函数中创建一个全局变量
nonlocal(只有在函数中声明函数的时候才需要用到)
改变函数中函数里的变量作用域中,使其能够改变上层函数的变量值
返回值
返回值:
a.就是函数返回给调用者值
b.就是return关键字后面的表达式的值
c.就是函数调用表达式的值
Python中每个函数都是有返回值的,返回值就是return后面的值。
如果函数中没有return,那么函数的返回值就是None。
递归函数:在函数的函数体中调用函数本身
特点:循环能做的的事情,递归都可以做
声明递归函数:
a.找临界值(跳出循环 -> return)
b.找关系:假设当前函数对应的功能已经实现,找到f(n)和f(n-1)的关系
c.使用f(n-1)与前面找到关系去实现f(n)的功能
对递归的要求:能不用就不用
函数调用的过程就是一个压栈的过程(每调用一次函数,系统都为其分配内存空间,
用来存储函数的变量,调用结束的时候系统自动释放内存资源)
匿名函数
本质:以另外一种简单的方式来声明
匿名函数的声明:
lambda 参数列表:返回值 --->结果是一个返回值
比较简单的函数使用匿名函数书写
文件操作
read -- 'r'/'rb' write --'w'/'a'/'wb'
with open()as 文件变量名:
文件操作
json 文件
json文件(文本),就是文件后缀是.json的文件。内容必须是json格式的内容
json格式:
1、内容是字符串
2、最外层是字典,字典里面就必须是键值对
3、最外层是数组(列表),数组里面内容必须是数组类型
json.load(文件变量名) json.dump(写的内容,文件对象名)
loads(字符串,编码方式) ---> 将指定的字符串,转换成json数据
(将字符串转换成字典、将字符串转换成列表)
dumps(对象) -- 将对象转换成json字符串
pygame
基本流程:
初始化(init) -- 创建窗口 -- 游戏循环 -- 检测事件
# 1.初始化pygame
pygame.init()
# 2.创建游戏窗口
# set_mode((宽度, 高度))
screen = pygame.display.set_mode((600, 400))
# 3.游戏循环
while True:
# 检测事件
for event in pygame.event.get():
pass
# 检测窗口上的关闭按钮是否被点击
if event.type == pygame.QUIT:
# 退出游戏
print('关闭按钮被点击')
exit()
# 其他操作
显示文字、图片、图形等
pygame中操作类似于作画。动画原理是基于对画布的不断刷新。
文字:
创建文字字体(系统、自建)
SysFont(name, size, bold=False, italic=False)/font = pygame.font.Font('./font/HYShangWeiShouShuW.ttf', 22)
根据字体去创建显示对象(文字)
render(self, text, antialias, color, background=None)
将内容添加到窗口上
blit(需要显示的对象, 显示位置)
将窗口上的内容展示出来
pygame.display.flip()
图片:
获取图片对象
image = pygame.image.load('./images/luffy.jpeg')
将图片对象渲染到窗口上
screen.blit(image, (0, 0))
展示在屏幕上
pygame.display.flip()
画图形则依赖于python中的一些函数
鼠标事件
代码添加位置:事件检测
鼠标事件关心鼠标位置与点击与否
pos属性,获取鼠标事件产生的位置
MOUSEBUTTONDOWN -- 鼠标按下
MOUSEBUTTONUP -- 鼠标弹起
小应用
先在屏幕上显示一张图片,鼠标按下移动的时候,拽着图片一起动。鼠标弹起就不动了。
import pygame
import 鼠标事件的应用
if __name__ == '__main__':
pygame.init()
screen = pygame.display.set_mode((800, 600))
screen.fill((255, 255, 255))
pygame.display.set_caption('图片拖拽')
image = pygame.image.load('./bb.ico')
image_x = 50
image_y = 50
screen.blit(image, (image_x, image_y))
pygame.display.flip()
# 用来存储图片是否可以移动
is_move = False
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
# 鼠标按下,让状态可以变成移动
if event.type == pygame.MOUSEBUTTONDOWN:
w, h = image.get_size()
if 鼠标事件的应用.isInRect(event.pos, (image_x, image_y, w, h)):
is_move = True
# 鼠标弹起,让状态可以变成不可以移动
if event.type == pygame.MOUSEBUTTONUP:
is_move = False
# 鼠标移动对应的事件
if event.type == pygame.MOUSEMOTION:
if is_move:
screen.fill((255, 255, 255))
x, y = event.pos
image_w, image_h = image.get_size()
image_x = x - image_w / 2
image_y = y - image_h / 2
screen.blit(image, (x - image_w / 2, y - image_h / 2))
pygame.display.update()
键盘事件
代码添加位置:事件检测
键盘事件关心键盘按键按下与否与所按键盘的值
key属性,被按的按键对应的值的编码
KEYDOWN 键盘按键按下
KEYUP 键盘按键弹起
小应用
通过键盘上的方向键控制一定移动速度的小球,避免小球碰到边界。并设置边界致死界定,算是一个基本的小游戏。
import pygame
def draw_ball(place, color, pos):
pygame.draw.circle(place, color, pos, 20)
# 方向对应的key值
Up = 273
Down = 274
Left = 276
Right = 275
if __name__ == '__main__':
pygame.init()
screen = pygame.display.set_mode((800, 600))
screen.fill((255, 255, 255))
pygame.display.flip()
# 保存初始坐标
ball_x = 400
ball_y = 300
x_speed = 1
y_speed = 1
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
if event.type == pygame.KEYDOWN:
if event.key == Up:
x_speed = 0
y_speed = -1
elif event.key == Down:
x_speed = 0
y_speed = 1
elif event.key == Right:
x_speed = 1
y_speed = 0
elif event.key == Left:
x_speed = -1
y_speed = 0
# 刷新屏幕
pygame.time.delay(10)
screen.fill((255, 255, 255))
ball_x += x_speed
ball_y += y_speed
if ball_x + 20 >= 800 or ball_x <= 20 or ball_y + 20 >= 600 or ball_y <= 20:
print('游戏结束')
exit()
# ball_x = 600 - 20
# x_speed *= -1
# if ball_x <0:
# ball_x = 0
# x_speed *= -1
draw_ball(screen, (255, 0, 0), (ball_x, ball_y))
pygame.display.update()
面向对象
类:对拥有相同属性和功能的对象的封装(抽象、相同的属性的值是不确定的)
对象:对象就是类的实例(具体,属性的值是确定的)
类:
声明格式:
class 类名(父类):
属性
方法
class:Python中声明类的关键字
类名:标识符,类名的首字母大写,驼峰式命名
(父类):类要继承自其它类,需要写括号,括号里面是父类的名字。可省略
属性:对象属性和类的字段 --- 保存数据
方法:实质就是声明在类中的函数 --- 实现功能
属性:对象的属性(属性)、类的属性(类的字段)
对象属性:属于对象的,不同对象对应的值可能不一样
类的属性:声明在类里面,函数外面。类的属性属于类(类的字段,通过类来使用)
方法:对象方法(方法)、类方法、静态函数
对象方法:自带一个self参数,一般要通过对象去掉用
类方法:1、使用@classmethod修饰,2、自带一个cls参数,并且这个参数不用传参,谁来调用这个方法,cls就指向谁,3、类方法通过类来调用
静态函数:使用staticmethod修饰,没有默认参数,通过类来调用
怎么选择用对象方法、类方法、静态方法?
if 如果实现函数的功能需要使用对象的属性,就声明成对象方法;
elif 如果实现函数的功能需要使用类的字段或者调用类的方法,就声明成类方法;
else 如果实现函数的功能即不需要使用对象的属性,也不需要使用类的字段或者调用类的方法,就声明成静态方法
内置类属性:python中每个类都拥有内置的类属性
1.类._name_
获取类的名字(str)
2.类._doc_
获取类的说明文档
3.类._dict_ 获取类中所有的类属性和对应的值,以键值对的形式存到字典中
对象._dict_ 将对象的属性和对应的值,转换成字典的元素(常用)
4.类._module_ 获取当前类所在的模块的名字
5.类._bases_ 获取当前类的父类及父类所在模块(返回结果为元组--为python中多继承服务)
对象
声明对象:
class 类名:
def def __init__(self):
self.属性名 = 初值
self2.属性名 = 初值
通过类的构造方法去创建对象(名字和类名同名的方法就是构造方法,自动生成)
对象名 = 类名()
init方法是系统自带的一个方法,这个方法不能直接调用,通过类创建对象的时候系统会自动调用这个方法
init方法的作用是对对象的属性进行初始化
通过构造方法创建对象的时候,一定要保证,init方法中除了self以外,其它的每个参数都必须有值
类对象可以通过点语法使用类中声明的对象的方法和属性
对象.方法名
对象.属性名
对象属性的增删查改:
查:
方法一:对象.属性(如果属性不存在,会报错AttributeError)
方法二:对象.getattribute('属性名')
方法三:getattr(对象, '属性名','默认值')(如果设置了default的值,那么当属性不存在的时候不会报错,并且返回默认值)
改:
方法一:对象.属性 = 新值
方法二:对象._setattr_('属性名','新值')
方法三:setattr(对象, '属性名','新值','默认值')
增:(setattr)
对象.属性 = 值(属性不存在)
注意:属性是添加给对象的,而不是类的
删:(delattr)
del 对象.属性
注意:删除属性也是删的具体某个对象的属性。不会影响这个类的其他对象
python中类中的属性和方法的私有化:直接在属性名或者方法名前加_(命名的以’_'开头)
属性或者方法私有:在外部不能直接使用,可以在类的内部使用
属性假的私有化:声明对象属性的时候,在属性名前面加一个'_',来告诉别人这个属性不可以直接使用。
要通过getter和setter来获取属性的值和修改属性的值。
1.getter:获取属性的值
@property
def 属性名(去掉下划线)(self):
return 返回值
如果在获取对象的某个属性前需要再干点别的事情,就给属性添加getter
2.setter:给属性赋值
一个属性必须要有getter,才能添加setter。
@属性名(去掉下划线).setter
def 属性名去掉下划线(self,变量名)
给带下划线的属性赋值
如果在给对象的某个属性赋值前需要再干点别的事情,就给属性添加setter
继承
子类:继承者
父类(超类):被继承者
1、继承基础
Python中类是可以继承的,并且支持多继承(一般使用单继承)
class 类名(父类列表):
'''类的说明文档'''
属性
方法
说明:Python中所有的类默认继承Python的基类:object
2、继承内容
继承:直接拥有父类的属性和方法(继承后父类的属性和方法还是存在的)
a.对象的属性和方法、类的字段和方法、静态方法都可以继承(私有的继承无意义--不能继承)
b._slots_的值不会被继承
c.getter和setter可以被继承
重写
继承后,子类可以拥有除父类继承的内容以外的其它的内容
父类不能使用在子类中添加的内容
1、关于方法
a.在子类中可以直接添加其它的方法
b.重写:
1)完全重写
重新实现从父类继承下来的方法,重写后,子类再调用这个方法的时候,就调用子类的
2)保留父类实现的功能,在添加新的功能
对象和类调用方法的过程: 先看当前类是否存在这个方法,没有才看父类有没有这个方法,如果父类没有,就看父类的父类有没有,直到找到基类为止(object)。
2、关于对象属性
对象属性的继承:通过继承init方法来继承对象属性
给当前类添加对象属性:重写init方法。
注意:如果要保留父类的对象属性使用super()
多态:同一个事物有多种形态。子类继承父类的方法,就可以对方法进行重写,一个方法就有多种形态(多态的表现)
重载
方法重载:一个类中可以有多个名字相同的方法,但是参数不一样,就叫重载。Python中不支持方法的重载,后面的会覆盖之前的。
运算符重载:
>(gt)、<(lt)
大于和小于符号只需要重载其中的一个,另外一个的结果,直接就是对重载所得到结果的取反的结果
+(add)、-(sub)
{如果记不清楚了,可以通过Ctrl + 鼠标左边点击进入查看重载方法的表示。}
正则表达式
符号 | 说明 |
---|---|
. | 匹配(点的个数个)任意字符 |
\w [W] | 匹配( \w的个数个)字符是[非]字母、数字或者下划线 |
\s [S] | 匹配( \s的个数个)[非]空白字符(空格、换行、制表符) |
\d [D] | 匹配( \d的个数个)[非]数字字符 |
\b [B] | 检测[非]边界(单词边界--一般的符号都可以作为单词边界) |
^ | 检测字符串开始(^The --检测以The开头的字符串) |
$ | 检测字符串结束 |
[] | 匹配[]中出现的任意一个字符 |
[^] | 匹配不在[]中出现的任意一个字符 |
* | 匹配0次或者多次 |
+ | 匹配一次或者多次 |
? | 匹配零次或者一次 |
{N} | 匹配N次 |
{N,} | 匹配大于等于N次 |
{M.N} | 匹配最少M次,最多N次 |
| | 分支 |
() | 匹配的时候是分组,让括号中的正则条件变成一个整体,进行整体操作 |
正则表达式里面出现? | 进入懒惰模式(常用于数据过滤) |
*? | 重复任意次,尽可能少的重复 |
+? | 重复任意次,最少重复一次,尽可能少的重复 |
?? | 重复0次或一次,尽可能少的重复 |
{N,}? | 重复至少N次,尽可能少的重复 |
{N,M}? | 重复N-M次,尽可能少的重复 |
re模块方法
compile(正则字符串)
将正则表达式字符串转换成正则表达式对象
转换成正则表达式对象后,可以通过对象调用相关的方法
fullmatch(正则表达式,字符串)
完全匹配,从字符串开头匹配到结尾
返回值是匹配对象,如果匹配失败返回None
应用:判断一个字符串是否是某种字符串(判断账号、密码是否符合要求等)
match(正则表达式,字符串)
不完全匹配,从字符串开头匹配,匹配到正则表达式对应的范围为止
返回值是匹配对象,如果匹配失败返回None
应用:判断一个字符串是否以某种字符串开头
search(正则表达式,字符串)
在指定的字符串找到某种字符串(以正则表达式来描述)
应用:判断一个字符串中是否包含某种字符串
findall(正则表达式,字符串)
去获取指定字符串中满足正则条件的所有字符串
返回值是列表,列表中是符合要求的字符串。没有满足要求的字符串就返回[]
注意:在通过正则表达式获取子串的时候,可以通过正则表达式中添加括号,来约束获取的内容(只捕获括号中匹配到的内容)
匹配的时候还是按原正则表达式去查找
应用:字符串提取
finditer(正则表达式,字符串)
用法和findall一样,只是返回值的类型不一样
返回一个迭代器
注意:()捕获部分无效
result = re.finditer(r'[a-z](\d+)', '123fdgv2324dfg')
for math in result:
print(match)
split(正则表达式,字符串)
按正则表达式匹配到的字符串进行切割
返回值是列表,列表元素就是切割后被分段的字符串
sub(正则表达式,repl,字符串)在原字符串中查找符合正则的子串,替换成repl