Phthon
2021-03-04 20:22:41 10 举报
AI智能生成
python笔记
作者其他创作
大纲/内容
面向对象
继承
特点
子类默认拥有父类的所有属性和方法
子类可以重写父类同名方法和属性
子类可以调用父类同名方法和属性
子类可以重写父类同名方法和属性
子类可以调用父类同名方法和属性
super()
有参数
super(当前类名, self).函数()
super(当前类名, self).函数()
无参数
super().函数()
super().函数()
私有权限
定义
属性或方法名前加两个下划线的, 为私有属性或方法
获取和修改
在类中, 添加get_...()和set_...()方法
其他
三大特性
封装
将属性和方法书写到类的里面的操作即为封装
封装可以为属性和方法添加私有权限
继承
子类默认继承付了的所有方法
子类有重写父类属性和方法
多态
传入不同的对象, 产生不同的结果
多态
定义
多态是一种使用对象的方法,
子类重写父类方法,
调用不同子类对象的相同父类方法,
可以产生不同的执行结果
子类重写父类方法,
调用不同子类对象的相同父类方法,
可以产生不同的执行结果
实现步骤
1.定义父类, 并提供公共方法
2.定义子类, 并重写父类方法
3.传递子类对象给调用者, 可以看到不同子类执行效果不同
类属性和实例属性
类属性
值的修改
类.类属性 = 值
通过对象, 不能修改类属性,
如果用对象.类属性 = 值,
实现的是, 创建了一个和类属性同名的实例属性
如果用对象.类属性 = 值,
实现的是, 创建了一个和类属性同名的实例属性
类方法
加@classmethod的方法
要使用类属性时用
静态方法
加@staticmethod的方法
不使用类属性时用
实例属性
__dict__
类.__dict__
返回类内部所有属性和方法对应的字典
对象.__dict__
返回实例属性和值组成的字典
异常
try
except
except
多个可能异常同时处理
在except后面, 写想要捕获异常类型的元祖
except (NameError, ZeroDivisionError)
except (NameError, ZeroDivisionError)
捕获所有类型的异常
Exception
捕获异常后打印异常信息
except NameError as return
return是保存异常信息的变量名
return是保存异常信息的变量名
else
没有异常时, 执行的代码
finally
无论是否异常, 都要执行的代码
自定义异常
创建
异常类要继承Exception
用raise抛出
异常类的__str__()方法的返回值,
是异常被捕获时的异常信息
是异常被捕获时的异常信息
模块和包
导入方式
import 模块名
使用
模块名.方法名()
模块名.方法名()
from 模块名 import 方法名
from 模块名 import *
import 模块名 as 模块别名
使用
模块别名.方法名()
模块别名.方法名()
不能用原模块名了
from 模块名 import 功能 as 方法别名
使用
方法别名()
方法别名()
不能用原方法名了
制作模块
测试代码
(这样写, 模块里, 既能保留测试代码,
又不会让模块被使用的时候, 执行测试代码)
(这样写, 模块里, 既能保留测试代码,
又不会让模块被使用的时候, 执行测试代码)
if __name__ == '__main__':
测试代码...
测试代码...
模块定位顺序
搜索顺序
1.当前目录
2.shell变量PYTHONPATH下的每个目录
3.默认路径
UNIX下, 默认路径一般为/usr/local/lib/python/
UNIX下, 默认路径一般为/usr/local/lib/python/
功能名重复的时候, 调用的是最后定义或导入的功能
__all__
用法
在模块中添加一行, 值为要被*导入的方法名的列表
__all__ = ['', ...]
在调用文件中, 模块引用必须得是from xxx import *
__all__才能起作用
__all__ = ['', ...]
在调用文件中, 模块引用必须得是from xxx import *
__all__才能起作用
作用
只有__all__中的方法, 才会被*导入
包导入
import 包.模块
使用
包.模块.方法()
包.模块.方法()
from 包 import *
__init__.py里必须要添加__all__ = ['模块1', ...]
控制允许导入的模块列表
控制允许导入的模块列表
使用
模块.方法()
模块.方法()
linux
主要目录
/bin
可执行二进制文件的目录
/etc
系统配置文件存放的目录
/home
用户家目录, 含有不同用户数据
命令
查看
ls
查看当前目录信息
ls 含有通配符的字符串
模糊查询匹配的文件
选项
-l
以列表方式显示
-h
文件大小后会显示单位, 默认是字节
-a
显示隐藏文件和目录
ll 等价于 ls -la
通配符
*
代表0个或多个任意字符
?
代表任意一个字符
tree
以树状方式显示目录信息
tree 文件夹名, 可以查看指定文件夹的树状信息
tree 文件夹名, 可以查看指定文件夹的树状信息
pwd
查看当前目录路径
clear
清除终端内容
切换目录
cd 目录
切换到指定目录
cd ~
切换到当前用户的主目录
cd
效果和cd ~相同
cd ..
切换到上一级目录
cd .
切换到当前目录
cd -
切换到上一次目录
cd ../..
切换到上上级目录
创建文件及目录
touch 文件名
创建指定文件
多个文件同时创建
touch 文件1 文件2
touch 文件1 文件2
mkdir 目录名
创建目录(文件夹)
多个文件夹同时创建
mkdir 文件夹1 文件夹2
mkdir 文件夹1 文件夹2
选项 -p
创建所依赖的文件夹
即, 如果创建A/B文件夹,
A不存在, 会同时创建A文件夹,
和A里面的B文件夹
即, 如果创建A/B文件夹,
A不存在, 会同时创建A文件夹,
和A里面的B文件夹
删除文件及目录
rm 文件
删除指定文件, 不能删目录
rm 选项
-i
系统会提示, 要不要删除
-r
递归删除目录及其内容
-f
强制删除, 如文件不存在, 不提示
-d
删除空目录
rmdir 目录名
删除空目录
复制和移动
cp 被拷贝文件 拷贝到地点
拷贝文件, 不能拷贝目录
特殊, 文件更名
cp 1.txt ./11.txt
cp 1.txt ./11.txt
通配符
*
代表0个或多个任意字符
?
代表任意一个字符
cp 选项
-i
如果拷贝地点有一样的文件, 会提示是否覆盖
就算选否, 文件名没重复的文件, 会被成功拷贝
就算选否, 文件名没重复的文件, 会被成功拷贝
没-i
文件名重复的话, 会被直接覆盖
-r
递归拷贝目录及其内容
-v
显示拷贝后的路径描述
-a
保留文件的原有权限
主要针对其他用户的权限
主要针对其他用户的权限
加了-a, 拷贝文件夹, 可以不加-r
且文件夹里面的权限, 也不丢失
且文件夹里面的权限, 也不丢失
mv 被移动 移动到
选项
-i
文件夹重复, 会提示是否覆盖
如果否, 任何文件或文件夹都不会改变
如果否, 任何文件或文件夹都不会改变
没 -i
文件夹重复会报错
-v
显示移动后的路径描述
移动文件和目录
如果 移动到 存在
如果 移动到 是文件, 且存在,
那么原来位置的文件, 会被覆盖
那么原来位置的文件, 会被覆盖
重命名
如果 移动到 不存在
通配符
*
代表0个或多个任意字符
?
代表任意一个字符
重定向
把在终端执行命令的结果, 保存到目标文件中
>
ls > info.txt
覆盖文件原来内容
>>
ls >> info.txt
在文件内容末尾追加
查看文件内容
cat
把文件所有内容打印出来
cat 1.txt
more
分屏查看文件内容
more 1.txt
| (管道)
管道, 存储终端数据的容器
用于长内容, 分页查看
用于长内容, 分页查看
ls /bin | more
gedit
查看且修改
链接
ln -s
创建软链接
删掉源文件
软链接失效
软链接失效
ln -s 源文件路径(绝对路径) 软连接路径
如果源文件路径是相对路径, 如1-s1,
软连接和源文件不在一个路径下,
软连接会找软链接当前路径下的1-s1文件
就会找不到
软连接和源文件不在一个路径下,
软连接会找软链接当前路径下的1-s1文件
就会找不到
ln
创建硬链接
两个路径, 指向同一份数据
两个路径, 指向同一份数据
删掉源文件
硬链接不失效
硬链接不失效
不能用于文件夹
ln -s 源文件路径 硬连接路径
文本搜索
grep
在文件中搜索内容
grep 查询内容 文件路径
选项
-i
忽略大小写
-n
显示匹配行号
-v
显示不包含匹配文本的所有行
正则表达式
^
以指定字符串开头
grep ^查询内容 文件路径
$
以指定字符串结尾
grep 查询内容$ 文件路径
.
匹配一个非换行符的字符
grep 查.询内容 文件路径
管道
ls /bin | grep 查询内容
文件查找
find
find 目录路径 -name 文件或目录名
在指定目录下查找文件或目录
选项
-name
根据文件名或目录查找
-iname
根据文件名或目录查找,
不区分大小写
不区分大小写
通配符
*
代表0个或多个任意字符
?
代表任意一个字符
压缩和解压缩
支持格式
.gz
.bz2
.zip
tar
压缩和解压缩
tar -czf test.tar.gz *.txt
表示将后缀是.txt的文件都打包压缩
选项
-c
创建打包文件
-v
显示打包或者解包的详细信息
-f
指定文件名称, 必须放到所有选项后面
-z
压缩或者解压缩(.gz)
-j
压缩或者解压缩(.bz2)
-x
解包
-C
解压缩到指定目录
tar -xzf 压缩文件名 -C 解压到的路径
只有-C是放在文件名和解压路径中间的
其他选项放在命令后面
其他选项放在命令后面
zip
压缩成.zip格式文件
zip 压缩后文件名(不加.zip, 默认会加上) 被压缩文件名
unzip
解压缩.zip格式文件
unzip 待解压的压缩文件名
-d
解压缩到指定目录
unzip 待解压的压缩文件名 -d 解压到路径
文件权限
chmod
修改文件权限
修改方法
字母法
chmod u-r 文件名
当前用户, 去除读权限
角色, 操作符和权限,
中间不要有空格
中间不要有空格
多角色同时设置
chmod u=rw,g=r,o=r 文件名
角色
u
user, 表示该文件的所有者
g
group, 表示用户组
o
other, 表示其他用户
a
all, 表示所有用户
操作符
+
增加权限
-
撤销权限
=
设置权限
权限
r
可读
w
可写
x
可执行
-
无任何权限
数字法
chmod 644 文件名
3个数字, 分别代表u, g, o角色
同时拥有两个权限, 把两个权限数字相加
如果只有两个数字, 如64,
效果等同于064
效果等同于064
权限
4
可读
2
可写
1
可执行
0
无任何权限
which
查询python解释器路径
which python3
查询命令路径
which ls
#作用
# 注释内容
表示一个注释
#_*_coding:utf-8_*_
指定文件编码格式
#!/python解释器路径
表示操作系统直接执行文件选择的解释器
执行文件
让文件默认用某种方式执行
在文件第一行加上
#!解释器路径
#!解释器路径
./文件名
执行当前层文件
./../文件名
执行上一层文件
获取管理员权限
sudo -s
切换到root用户, 获取管理员权限
sudo 命令
命令以管理员权限执行
exit
退出管理员权限
whoami
查看当前用户
passwd
修改当前用户密码
passwd 用户名
修改指定用户密码
who
当前系统, 登陆了哪些用户
shutdown -h now
立刻关机
reboot
重启
用户相关操作
useradd
创建(添加)用户
useradd -m 用户名
选项
-m
自动创建用户主目录, 主目录的名字, 就是用户名,
如, home目录下, 一般会有用户名的文件夹, 主目录,
就是指这个文件夹
如, home目录下, 一般会有用户名的文件夹, 主目录,
就是指这个文件夹
-g
指定用户所属的用户组, 默认不指定会自动创建一个同名的用户组
useradd -m -g 用户组 用户
cat /etc/passwd 查看用户是否成功创建
cat /etc/group 查看用户组是否成功创建
cat /etc/group 查看用户组是否成功创建
切换到新用户, 只有一个$解决办法
root@ubuntu:~# vi /etc/passwd
把对应用户后面的/bin/sh改成/bin/bash
把对应用户后面的/bin/sh改成/bin/bash
id 用户名
查用户信息
passwd 用户名
修改指定用户密码
su - 用户名
切换用户
修改用户信息
usermod
选项
-G(只能作为最后一个选项)
设置一个附加组
usermod -G 附加组名 用户名
给用户设置附加组为sudo,
之前的组, 会被清除
给用户设置附加组为sudo,
之前的组, 会被清除
-a
不清除原来附加组的基础上,
添加附加组
添加附加组
-g
修改用户组
usermod -g 用户组 用户
新建用户, 获取使用sudo命令权限
添加sudo和adm两个附加组
gpasswd
添加删除附加组
命令
-a
添加附加组
sudo gpasswd -a 用户名 附加组名
-d
删除附加组
sudo gpasswd -d 用户名 附加组名
userdel -r 用户名
删除用户
默认会删除同名的用户组
如果不加-r, 用户主目录不会删除
用户组相关操作
groupadd
创建(添加)用户组
groupadd 用户组
groupdel
删除用户组
用户组下面有用户, 不能删除用户组
远程登陆和远程拷贝
ssh
远程登陆
退出远程
ctrl + d
scp
远程拷贝
本地拷贝文件到服务器
scp 本地文件路径 用户名@ip:拷贝到的路径
服务器拷贝文件到本地
scp 用户名@ip:拷贝文件名 本地路径
ssh -V
查看客户端有没有安装
查看服务端软件有没有安装
apt list | grep openssh-server
ps -e |grep ssh
显示
ssh-agent
表示客户端启动了
ssh-agent
表示客户端启动了
ssh-agent没有, 执行下面命令, 安装客户端
sudo apt-get install openssh-client
sudo apt-get install openssh-client
显示
sshd
表示服务端启动了
sshd
表示服务端启动了
sshd没有, 执行下面命令, 安装服务端
sudo apt install openssh-server
sudo apt install openssh-server
apt list
查看电脑安装的所有程序
命令帮助
命令 --help
man 命令
界面操作
空格
显示下一屏信息
回车
显示下一行信息
b
显示上一屏信息
f
显示下一屏信息
q
退出
终端命令格式
command [-options] [parameter]
command
命令名, 如ls, pwd
[-options]
选项, 可以有零个, 一个, 或多个, 且多个能合到一起写,
如-r, -l -h, -lh
如-r, -l -h, -lh
[parameter]
参数, 可以有零个, 一个, 或多个, 如 touch 文件名, cd 目录,
这些文件名和目录都是参数
这些文件名和目录都是参数
[]
代表可选
选项的作用
用于调整命令的功能
长短选项
短选项
'-' 后面接单个字母, 如-r
长选项
'--' 后面接单词, 如--help
参数
命令的操作对象
一般是文件名或者目录名
顺序
选项和参数的顺序一般没有要求
但, scp命令必须先选项, 后参数
但, scp命令必须先选项, 后参数
绝对路径和相对路径
绝对路径
从根目录算起的路径
如
/home/python/Desktop
/use/bin
相对路径
从当前目录算起的路径
如
./test/hello
test/hello
../static/images
上一级目录下的static下的images文件夹
vim
工作模式
命令模式
编辑模式
i 由命令模式进入编辑模式
:w
保存
:wq
:x
:q!
不保存, 强制退出
末行模式
常用命令
yy
复制光标所在行
p
粘贴
dd
删除/剪切当前行
V
选中当前行
V + G 选中当前行及下面的所有行
u
撤销
ctrl + r
反撤销
>>
往右缩进
<<
往左缩进
:/搜索的内容
搜索指定内容
n
下一个
N
上一个
:%s/要替换的内容/替换后的内容/g
全局替换
:/开始行数,结束行数s/要替换的内容/替换后的内容
局部替换
.
重复上一次命令操作
G
回到最后一行
gg
回到第一行
数字 + G
回到指定行
shift + 6
回到当前行的行首
shift + 4
回到当前行的行末
ctrl + f
下一屏
ctrl + b
上一屏
软件安装
安装方式
离线安装
安装包格式
mac
.dmg
ubuntu
.deb
windows
.exe
sudo dpkg -i 包名
-i
安装
安装过程中, 显示正在设置/Setting up
后面的内容是安装的包名
后面的内容是安装的包名
在线安装
sudo apt-get install 安装包
修改国内镜像
可视化修改
打开Software & Updates
DownLoad from选项, 里面选Other, 然后选China下的镜像, 选阿里, 或者清华
在命令行, 执行sudo apt-get update, 更新最新软件列表
测试是否成功
sudo apt-get install sl
输入sl, 会出现一个火车动画
手动更改
https://developer.aliyun.com/mirror/
复制对应系统的镜像文件内容
覆盖以下文件
gedit /etc/apt/sources.list
gedit /etc/apt/sources.list
在命令行, 执行sudo apt-get update, 更新最新软件列表
测试是否成功
sudo apt-get install sl
输入sl, 会出现一个火车动画
卸载
卸载离线安装包
查找安装包名, 用于卸载
sudo dpkg -l 模糊查找*
sudo dpkg -r 安装包名
卸载在线安装包
apt-get remove 安装包
解决不能复制粘贴
sudo apt-get autoremove open-vm-tools
sudo apt-get install open-vm-tools
sudo apt-get install open-vm-tools-desktop
sudo apt-get install open-vm-tools
sudo apt-get install open-vm-tools-desktop
快捷键
ctrl + shift + '+'
终端字体方法
ctrl + '-'
终端字体缩小
ctrl + alt + t
快捷启动终端
多任务
并发
在一段时间内交替执行任务
并行
多个内核一起执行软件
其他
多进程开发比单进程多线程开发, 稳定性要强, 但占用资源多
进程可以用多核
线程不能用多核
使用场景
进程
计算密集型相关操作
因为可以用多核
因为可以用多核
线程
文件写入, 下载, IO操作
进程
定义
实现多任务的一种方式
一个正在运行的程序或者软件, 就是一个进程
它是操作系统进行资源分配的基本单位
它是操作系统进行资源分配的基本单位
一个进程, 默认有一个线程, 一个进程可以创建多个线程
创建子进程, 其实是对主进程资源进行拷贝,
子进程其实就是主进程的一个副本
子进程其实就是主进程的一个副本
操作系统调用进程
使用
导包
import multiprocessing
import multiprocessing
创建进程对象
multiprocessing.Process(target=进程要执行的方法名)
参数
group
指定进程组目前只能使用None
target
执行的目标任务名
name
进程名字
默认是Process-N
N从1开始递增的整数
N从1开始递增的整数
args
以元祖方式给执行任务传参
kwargs
以字典方式给执行任务传参
Process参数
args
元祖
kwargs
字典
执行进程
进程对象.start()
python每次创建子进程都会先把主进程中的代码当成模块加载一遍
所以主进程执行的代码, 要用
if __name__ == '__main__':
包起来
如果不包起来, 在加载完所有进程前, 就会执行start(), 这是不允许的
所以主进程执行的代码, 要用
if __name__ == '__main__':
包起来
如果不包起来, 在加载完所有进程前, 就会执行start(), 这是不允许的
获取进程编号
获取当前进程编号
os.getpid()
获取父进程编号
os.getppid()
杀进程
强制杀死指定进程
os.kill(进程号, 9)
注意点
进程之间不共享全局变量
主进程会等待所有的子进程执行结束再结束
方法
start()
启动子进程实例
join()
当前进程等待添加数据的进程执行完成以后,
代码在继续执行
代码在继续执行
terminate()
销毁子进程
属性
daemon
True
把子进程设置成为守护主进程,
以后, 主进程执行完后, 子进程直接销毁
以后, 主进程执行完后, 子进程直接销毁
获取当前进程对象
multiprocessing.current_process()
线程
定义
线程是CPU调度的基本单位
线程需要CPU调度来完成
每个进程至少都有一个线程, 我们一般称之为主线程
线程之间共享全局变量
线程之间共享全局变量数据出现错误问题
使用
导模块
import threading
import threading
线程类Thread
参数
group
指定线程组目前只能使用None
target
执行的目标任务名
name
线程名
默认是Thread-N
N从1开始递增的整数
N从1开始递增的整数
args
以元祖方式给执行任务传参
kwargs
以字典方式给执行任务传参
daemon
True
子主题
子线程守护主线程,
主线程退出, 主线程直接销毁
主线程退出, 主线程直接销毁
方法
start()
启动线程
setDaemon(True)
设置是否守住主线程
join()
让当前(主)线程等待子线程执行完后, 再继续执行
获取当前线程对象
threading.current_thread()
互斥锁
创建锁
threading.Lock()
上锁
acquire()
释放锁
release()
网络编程
IP
作用
标识网络中唯一的一台设备
分类
IPv4
点分十进制
IPv6
冒分十六进制
两个冒号中间没有东西, 代表中间是4个0
查IP
Linux和macOS
ifconfig
Windows
ipconfig
域名
127.0.0.1对应的域名是localhost
域名是ip地址的别名
ping 127.0.0.1
检查本地网卡是否正常
端口
共65536个
0-65535
0-65535
分类
知名端口号
0-1023
动态端口号
1024-65535
TCP
传输控制协议
面向连接的, 可靠的, 基于字节流的传输层通信协议
通信步骤
创建连接
传输数据
关闭连接
特点
面向对象
通信双方必须先建立好连接才能进行数据的传输,
数据传输完成后, 双方必须断开此连接, 以示范系统资源
数据传输完成后, 双方必须断开此连接, 以示范系统资源
可靠传输
采用发送应答机制
超时重传
错误校验
流量控制和阻塞管理
socket
定义
进程之间通信的工具
导模块
import socket
创建socket对象
socket.socket(AddressFamily, Type)
参数
AddressFamily
分为IPv4和IPv6
Type
TCP
方法
connect((host, port))
和服务端套接字建立连接
参数(元祖)
host
服务器ip地址
port
应用程序端口号
send(data)
标识发送数据
data是二进制数据
recv(buffersize)
标识接收数据
buffersize是每次接收数据的长度
bind((host, port))
标识绑定端口号
参数(元祖)
host
IP地址(一般不指定)
port
端口号
listen(backlog)
标识设置监听
backlog
标识最大等待建立连接数
accept()
表示等待接受客户端的连接请求
返回
(新的套接字, (客户端ip, 客户端prot))
和客户端通信, 用这个返回的套接字,
不用创建连接的那个套接字
不用创建连接的那个套接字
TCP网络应用程序开发
客户端
步骤
创建客户端套接字对象
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.AF_INET
IPv4
socket.SOCK_STREAM
tcp传输类型
和服务端套接字建立连接
tcp_client_socket.connect(('192.168.48.1', 8080))
发送数据
s_data = '你好'.encode('gbk')
tcp_client_socket.send(s_data)
tcp_client_socket.send(s_data)
网络调试助手编码
windows
gbk
linux
utf-8
字符串转二进制
'字符串'.encode(编码方式)
接受数据
recv_data = tcp_client_socket.recv(1024)
print(recv_data.decode('gbk'))
二进制转字符串
二进制数据.decode(编码方式)
关闭客户端套接字
tcp_client_socket.close()
服务端
步骤
创建服务端套接字对象
# tcp_server_socket只负责等待接收客户端的连接请求,收发消息不使用该套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
绑定端口号
tcp_server_socket.bind(('', 9090))
设置监听
tcp_server_socket.listen(128)
等待接受客户端的连接请求
# 注意点: 每次当客户端和服务端建立连接成功都会返回一个新的套接字
# tcp_server_socket只负责等待接收客户端的连接请求,收发消息不使用该套接字
new_client, ip_port = tcp_server_socket.accept()
# tcp_server_socket只负责等待接收客户端的连接请求,收发消息不使用该套接字
new_client, ip_port = tcp_server_socket.accept()
接受数据
recv_data = new_client.recv(1024)
# 对二进制数据进行解码变成字符串
recv_content = recv_data.decode("gbk")
# 对二进制数据进行解码变成字符串
recv_content = recv_data.decode("gbk")
发送数据
send_content = "问题正在处理中..."
# 对字符串进行编码
send_data = send_content.encode("gbk")
# 6. 发送数据到客户端
new_client.send(send_data)
# 对字符串进行编码
send_data = send_content.encode("gbk")
# 6. 发送数据到客户端
new_client.send(send_data)
关闭套接字
# 关闭服务与客户端套接字,表示和客户端终止通信
new_client.close()
# 7. 关闭服务端套接字, 表示服务端以后不再等待接受客户端的连接请求
tcp_server_socket.close()
new_client.close()
# 7. 关闭服务端套接字, 表示服务端以后不再等待接受客户端的连接请求
tcp_server_socket.close()
多任务TCP服务端
循环调用accept(), 且创建线程,
线程内和客户端连接
线程内和客户端连接
当子线程没结束, 主线程不能关闭, 如果想要主线程关闭,
子线程一起关闭, 需要设置子线程守护主线程
子线程一起关闭, 需要设置子线程守护主线程
端口号复用
当客户端和服务端建立连接后,
服务端程序退出后端口号不会立即释放,
需要等待大概1-2分钟,
设置端口复用, 就能让端口立即释放
服务端程序退出后端口号不会立即释放,
需要等待大概1-2分钟,
设置端口复用, 就能让端口立即释放
# 设置端口号复用,表示意思: 服务端程序退出端口号立即释放
# 1. SOL_SOCKET: 表示当前套接字
# 2. SO_REUSEADDR: 表示复用端口号的选项
# 3. True: 确定复用
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 1. SOL_SOCKET: 表示当前套接字
# 2. SO_REUSEADDR: 表示复用端口号的选项
# 3. True: 确定复用
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
注意点
当 TCP 客户端程序想要和 TCP 服务端程序进行通信的时候必须要先建立连接
TCP 客户端程序一般不需要绑定端口号,因为客户端是主动发起建立连接的。
TCP 服务端程序必须绑定端口号,否则客户端找不到这个 TCP 服务端程序。
调用listen方法后的套接字是被动套接字,只负责接收新的客户端的连接请求,不能收发消息。
当 TCP 客户端程序和 TCP 服务端程序连接成功后, TCP 服务器端程序会产生一个新的套接字,收发客户端消息使用该套接字。
关闭 accept 返回的套接字意味着和这个客户端已经通信完毕。
关闭 listen 后的套接字意味着服务端的套接字关闭了,会导致新的客户端不能连接服务端,但是之前已经接成功的客户端还能正常通信。
当客户端的套接字调用 close 后,服务器端的 recv 会解阻塞,返回的数据长度为0,服务端可以通过返回数据的长度来判断客户端是否已经下线,反之服务端关闭套接字,客户端的 recv 也会解阻塞,返回的数据长度也为0。
HTTP协议和静态Web服务器
HTTP协议
超文本传输协议
传输HTTP协议格式的数据是基于TCP传输协议的,
发送数据之前需要先建立连接
发送数据之前需要先建立连接
HTTP协议规定了浏览器和Web服务器通信数据的格式
URL
统一资源定位符
组成部分
https://www.baidu.com/aaa/bbb.html
协议
https://
443
http://
80
ftp://
域名
www.baidu.com
IP地址的别名
资源路径
/aaa/bbb.html
查询参数部分(可选)
?page=1&count=10
HTTP请求报文
浏览器发送给web服务器程序的http协议数据
种类
GET
获取web服务器数据
POST
向web服务器提交数据
组成
请求行
请求方式
请求资源路径
HTTP协议版本
请求头
空行
请求体(GET没有)
HTTP响应报文
组成
响应行
HTTP协议版本
状态码
200
请求成功
307
重定向
400
错误的请求, 请求地址错误或者参数有误
404
请求资源在服务器不存在
500
服务器内部源代码出现错误
状态描述
响应头
空行
响应体
http报文解析
搭建静态Web服务器
为发出请求的浏览器提供静态文档的程序
python自带的Web服务器
python3 -m http.server 端口号
端口号不指定, 默认是8000
访问地址
http://ip:端口/文件路径
http://ip:端口/文件路径
前端
html
结构
<!DOCTYPE html>
<html>...</html>
MySQL
数据库分类
关系型数据库
强调使用表格的方式存储数据
核心元素
数据行
数据列
数据表
数据库(数据表的集合)
常用
Oracle
MySQL
Microsoft SQL Server
SQLite
非关系型数据库
强调Key-Value的方式存储数据
又被称为NoSQL
常用
MongoDB
Redis
数据库特点
持久化存储
读写速度极高
保证数据的有效性
SQL是结构化查询语言
SQL分类
DQL
数据查询语言
用于对数据进行查询, 如select
DML
数据操作语言
对数据进行增加. 修改, 删除, 如insert, update, delete
TPL
事务处理语言
对事务进行处理, 包括begin transaction, commit,rollback
DCL
数据控制语言
进行授权与权限回收, 如grant, revoke
DDL
数据定义语言
进行数据库, 表的管理等, 如create, drop
MySQL特点
Navicat
新建数据库
字符集
utf8 -- UTF-8 Unicode
必须指定utf8编码格式
否则出现中文会有乱码
否则出现中文会有乱码
排序规则
utf8_general_ci
通用的排序规则, 忽略大小写
如查询a, A也会查出来
utf8_bin
区分大小写
表结构操作
子主题
登陆和登出
登陆
mysql -uroot -p
-u 后面是登陆的用户名
-p 后面是登陆密码, 如果不填写, 之后会提示输入密码
查看是否登陆成功
select now();
显示当前时间
登出
quit
exit
ctrl + d
数据库操作的SQL语句
查看所有数据库
show databases;
创建数据库
create database 数据库名 charset=utf8;
使用数据库
use 数据库名;
查看当前使用的数据库
select database();
删除数据库
drop database 数据库名;
表结构操作的SQL语句
查看当前数据库中的所有表
show tables;
查看表结构
desc 表名;
创建表
create table students(
id int unsigned primary key auto_increment not null,
name varchar(20) not null,
age tinyint unsigned default 0,
height decimal(5,2),
gender enum('男','女','人妖','保密')
);
id int unsigned primary key auto_increment not null,
name varchar(20) not null,
age tinyint unsigned default 0,
height decimal(5,2),
gender enum('男','女','人妖','保密')
);
create table 表名(
字段名称 数据类型 可选的约束条件,
column1 datatype contrai,
...
);
字段名称 数据类型 可选的约束条件,
column1 datatype contrai,
...
);
修改表
添加字段
alter table 表名 add 列名 类型 约束;
如: alter table students and birthday datatime;
修改字段类型
modify 只能修改字段类型或者约束, 不能修改字段名
alter table 表名 modify 列名 类型 约束;
如: alert table students modify birthday date not null;
修改字段名和字段类型
修改字段名和字段类型, 可同时修改多个字段
change 既能对字段重命名又能修改字段类型, 还能修改约束
alter table 表名 change 原名1 新名1 类型及约束, 原名2 新名2 类型及约束;
如: alter table students change birthday birth datetime not null;
外键约束
对外键字段的值进行更新和插入时会和引用表中字段的数据进行验证,数据如果不合法则更新和插入会失败,保证数据的有效性
对于已经存在的字段添加外键约束
-- 为cls_id字段添加外键约束, classes表的id值存在, 才允许cla_id保存
alter table students add foreign key(cls_id) references classes(id);
alter table students add foreign key(cls_id) references classes(id);
创建数据表时设置外键约束
create table teacher(
id int not null primary key auto_increment,
name varchar(10),
s_id int not null,
foreign key(s_id) references school(id)
);
id int not null primary key auto_increment,
name varchar(10),
s_id int not null,
foreign key(s_id) references school(id)
);
删除外键约束
-- 需要先获取外键约束名称,该名称系统会自动生成,可以通过查看表创建语句来获取名称
show create table teacher;
CONSTRAINT `s_ibfk_1` FOREIGN KEY (`c_id`) REFERENCES `c` (`id`)
s_ibfk_1是外键名
show create table teacher;
CONSTRAINT `s_ibfk_1` FOREIGN KEY (`c_id`) REFERENCES `c` (`id`)
s_ibfk_1是外键名
-- 获取名称之后就可以根据名称来删除外键约束
alter table teacher drop foreign key 外键名;
alter table teacher drop foreign key 外键名;
删除字段
alter table 表名 drop 列名;
如: alter table students drop birthday;
删除表
drop table 表名;
如: drop table students;
查看创表SQL语句
show create table 表名;
如: show create table students;
查看创库SQL语句
show create database 数据库名;
如: show create database mytest;
表数据操作的SQL语句
查询数据
查所有列
select * from 表名;
查指定列
select 列1, 列2 from 表名;
添加数据
主键列自动增长, 但在全列插入时需要占位, 通常使用空值(0, null, default)
全列插入时, 如果字段列有默认值, 可以使用default来占位,
插入后的数据就是之前设置的默认值
插入后的数据就是之前设置的默认值
全列插入
insert into 表名 values ('小王', 15 ....)
部分列插入
insert into 表名(name, age) values('小王', 15)
全列多行插入
insert into 表名 values (值1,...), (值1,...)
部分列多行插入
insert into 表名(列1,...) values(值1,...),(值1,...)...;
插入查询结果
insert into 表(字段...) select ...
创建表并添加数据
create table .. select 列名 ..
查询出来的列名需和插入数据表的列名相同,
如不相同, 可用起别名的方式
如不相同, 可用起别名的方式
-- 创建商品分类表,注意: 需要对brand_name 用as起别名,否则name字段就没有值
create table good_brands (
id int unsigned primary key auto_increment,
name varchar(40) not null) select brand_name as name from goods group by brand_name;
create table good_brands (
id int unsigned primary key auto_increment,
name varchar(40) not null) select brand_name as name from goods group by brand_name;
修改数据
一般
update 表名 set 列1=值1,列2=值2... where 条件
例:
update students set age = 18, gender = '女' where id = 6;
例:
update students set age = 18, gender = '女' where id = 6;
连接更新
update 关联语句 set 表1.字段1 = 表2.字段2
-- 把该语句中from 后的语句理解为一张虚表
update goods g inner join good_cates gc on g.cate_name=gc.name set g.cate_name=gc.id;
update goods g inner join good_cates gc on g.cate_name=gc.name set g.cate_name=gc.id;
删除数据
delete from 表名 where 条件
例:
delete from students where id=5;
例:
delete from students where id=5;
逻辑删除
让一个字段, 作为删除标记
as
别名
字段别名
select id as 序号 from 表名;
表别名
select id from 表名 as 表别名
不加as, 直接加别名, 也能实现效果
select id 序号 from 表名;
select id from 表名 别名;
distinct
去重
select distinct 列1, ... from 表名;
例: 查询班级中学生的年龄
select distinct age from students;
select distinct age from students;
如果有多个字段, 多个字段都相同, 才算重复
where
运算符
比较运算符
等于: =
大于: >
大于等于: >=
小于: <
小于等于: <=
不等于: != 或 <>
大于: >
大于等于: >=
小于: <
小于等于: <=
不等于: != 或 <>
select * from 表名 where 列1 = '内容'
逻辑运算符
and
且, 需同时满足
se... where 列1 = '内容1' and 列2 = '内容2'
or
或, 满足一个即可
se... where 列1 = '内容1' or 列2 = '内容2'
not
非, 取反
select * from students where not (age >= 10 and age <= 15);
模糊查询
like是模糊查询关键字
%表示任意多个任意字符
_表示一个任意字符
%表示任意多个任意字符
_表示一个任意字符
select * from students where name like '_黄%'
查询名字中间为黄, 黄前面有一个字, 黄后面, 有0到任意多字的名字
范围查找
between .. and .. 表示在一个连续的范围内查询
select * from students where id between 3 and 8;
查询在3到8之间, 左右都包含
not between ... and...
select * from students where (not id between 3 and 8)
select * from students where not id between 3 and 8
select * from students where id not between 3 and 8
in 表示在一个非连续的范围内查询
select * from students where id in (1, 3);
查询id是1或3的
空判断
is null
为空
where id is null
is not nul
不为空
不能使用where id = null
排序
select * from 表名 order by 列1 asc或desc, 列2 asc或desc
先按照列1进行排序,如果列1的值相同时,则按照 列2 排序,以此类推
asc从小到大排列,即升序
desc从大到小排序,即降序
不加asc或desc, 默认按照列值从小到大排列
分页
select * from 表名 limit start,count
limit是分页查询关键字
start表示开始行索引,默认是0
limit 3;
表示前3行
count表示查询条数
查第n页, 每页m条数据
limit (n-1)*m, m
聚合函数
聚合函数不统计null值
count(col): 表示求指定列的总行数
max(col): 表示求指定列的最大值
min(col): 表示求指定列的最小值
sum(col): 表示求指定列的和
avg(col): 表示求指定列的平均值
ifnull
ifnull(列1, 0)
因为null不统计, 所以要加上ifnull, 才会把值为null的那行算进去
select avg(ifnull(height,0)) from students;
如果列为空, 就变成第二个参数的值
分组查询
定义
GROUP BY 列名 [HAVING 条件表达式] [WITH ROLLUP]
列名: 是指按照指定字段的值进行分组。
HAVING 条件表达式: 用来过滤分组后的数据。
例: group by 列1 having count(*) > 2
WITH ROLLUP:在所有记录的最后加上一条记录,
显示select查询时聚合函数的统计和计算结果
显示select查询时聚合函数的统计和计算结果
使用
多列分组
select name, gender from students group by name, gender;
效果同select distinct name, gender from students;
group by + group_concat()
select gender,group_concat(name) from students group by gender;
把相同gender的name, 用逗号拼接, 合成一个字段
group_concat()
把该列多行数据, 拼成一行, 用逗号隔开
group by + 聚合函数
select gender,avg(age) from students group by gender;
求相同gender的平均年龄
group by + having
select gender,count(*) from students group by gender having count(*)>2;
查询相同gender人数在2人以上的gender
group by + with rollup
-- 根据gender字段进行分组,汇总总人数
select gender,count(*) from students group by gender with rollup;
-- 根据gender字段进行分组,汇总所有人的年龄
select gender,group_concat(age) from students group by gender with rollup;
select gender,count(*) from students group by gender with rollup;
-- 根据gender字段进行分组,汇总所有人的年龄
select gender,group_concat(age) from students group by gender with rollup;
with rollup 只会对聚合函数进行汇总
连接查询
内连接
inner join ... on ...
查两个表的交集
inner join 就是内连接查询关键字
on 就是连接查询条件
select 字段 from 表1 inner join 表2 on 表1.字段1 = 表2.字段2
左连接
left join ... on ...
以左表为主根据条件查询右表数据,右表数据不存在使用null值填充
left join 就是左连接查询关键字
on 就是连接查询条件
select 字段 from 表1 left join 表2 on 表1.字段1 = 表2.字段2
右连接
right join ... on ...
以右表为主根据条件查询右表数据,右表数据不存在使用null值填充
right join 就是右连接查询关键字
on 就是连接查询条件
select 字段 from 表1 right join 表2 on 表1.字段1 = 表2.字段2
自连接
把一张表模拟成左右两张表,然后进行连表查询
必须给表起别名
如一个表里, 有省市信息, 查省市信息的关联关系
select c.id, c.title, c.pid, p.title
from areas as c
inner join areas as p
on c.pid = p.id
where p.title = '山西省';
from areas as c
inner join areas as p
on c.pid = p.id
where p.title = '山西省';
执行sql文件
source 文件名.sql
索引
主要用于提高数据库的查询速度
主键和外键约束会自动创建索引
语句
查看已有索引
show index from 表名;
创建
-- 创建索引的语法格式
-- alter table 表名 add index 索引名[可选](列名, ..)
-- 给name字段添加索引
alter table classes add index my_name (name);
-- alter table 表名 add index 索引名[可选](列名, ..)
-- 给name字段添加索引
alter table classes add index my_name (name);
索引名不指定,默认使用字段名
联合索引, 默认是第一个字段名
联合索引, 默认是第一个字段名
删除
-- 删除索引的语法格式
-- alter table 表名 drop index 索引名
-- 如果不知道索引名,可以查看创表sql语句
show create table classes;
alter table classes drop index my_name;
-- alter table 表名 drop index 索引名
-- 如果不知道索引名,可以查看创表sql语句
show create table classes;
alter table classes drop index my_name;
联合索引
alter table teacher add index (name,age);
作用
减少磁盘开销
最左原则
如果没有用到最左边的字段, 则不会走索引
index(name, age)
走索引
name = '...'
或者
name = '...' and age = '...'
或者
name = '...' and age = '...'
不走索引
age = '...'
只要有最左边的字段, 就会走索引
优点
加快数据查询速度
缺点
创建索引会耗费时间和占用磁盘空间,并且随着数据量的增加所耗费的时间也会增加
使用原则
通过优缺点对比,不是索引越多越好,而是需要自己合理的使用。
对经常更新的表就避免对其进行过多索引的创建,对经常用于查询的字段应该创建索引,
数据量小的表最好不要使用索引,因为由于数据较少,可能查询全部数据花费的时间比遍历索引的时间还要短,索引就可能不会产生优化效果。
在一字段上相同值比较多不要建立索引,比如在学生表的"性别"字段上只有男,女两个不同值。相反的,在一个字段上不同值较多可是建立索引。
时间
开启运行时间检测
set profiling = 1;
查看执行时间
show profiles;
事务
四大特性
ACID
ACID
A-原子性
一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性
C-一致性
数据库总是从一个一致性的状态转换到另一个一致性的状态。(在前面的例子中,一致性确保了,即使在转账过程中系统崩溃,支票账户中也不会损失200美元,因为事务最终没有提交,所以事务中所做的修改也不会保存到数据库中。)
I-隔离性
通常来说,一个事务所做的修改操作在提交事务之前,对于其他事务来说是不可见的。(在前面的例子中,当执行完第三条语句、第四条语句还未开始时,此时有另外的一个账户汇总程序开始运行,则其看到支票帐户的余额并没有被减去200美元。)
D-持久性
一旦事务提交,则其所做的修改会永久保存到数据库。
只有InnoDB和BDB引擎才可以使用事务
MySQL默认才用自动提交模式
pymysql
默认开启事务
conn.commit()
提交事务
conn.rollback()
回滚事务
命令
show engines
查看MySQL数据库支持的表的存储引擎
常用的存储引擎
InnoDB
支持事务
MyISAM
不支持事务, 但访问速度快
alter table 表名 engine = '存储引擎名'
修改表的存储引擎
开启事务
begin;
或者
start transaction;
或者
start transaction;
执行一次begin, 只能使用一次事务, commit后, 就失效了
如果还想使用事务, 需要再次执行begin
如果还想使用事务, 需要再次执行begin
set autocommit = 0
取消自动提交事务模式
只在当前窗口起作用,
关闭后失效
关闭后失效
commit
提交事务
rollback
回滚事务
远程登陆mysql, 服务端需要的配置
ubuntu系统
vim /eic/mysql/mysql.conf.d/mysqld.cnf
注释掉bind-address = 127.0,0,1
不注释, 客户端只能与127.0.0.1连接
database为mysql, user表
update user set host = '%' where user = 'root';
重启mysql
sudo service mysql restart;
格式化输出
select * from 表 \G;
数据库设计
三范式
第一范式(1NF): 强调的是列的原子性,即列不能够再分成其他几列。
第二范式(2NF): 满足 1NF,另外包含两部分内容,一是表必须有一个主键;二是非主键字段 必须完全依赖于主键,而不能只依赖于主键的一部分。
第三范式(3NF): 满足 2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况。
E-R模型
E-R模型即实体-关系模型,E-R模型就是描述数据库存储数据的结构模型。
power designer,db desinger
实体: 用矩形表示,并标注实体名称
属性: 用椭圆表示,并标注属性名称,
关系: 用菱形表示,并标注关系名称
一对一
一对多
多对多
属性: 用椭圆表示,并标注属性名称,
关系: 用菱形表示,并标注关系名称
一对一
一对多
多对多
关系也是一种数据,需要通过一个字段存储在表中
1对1关系,在表A或表B中创建一个字段,存储另一个表的主键值
1对多关系,在多的一方表(学生表)中创建一个字段,存储班级表的主键值
多对多关系,新建一张表C,这个表只有两个字段,一个用于存储A的主键值,一个用于存储B的主键值
PyMySQL
pymysql包
安装
sudo pip3 install pymysql
卸载
sudo pip3 uninstall pymysql
查看
pop3 show pymysql
pip3 list
创建连接对象
connect = Connection = Connect
conn=pymysql.connect(参数列表)
* 参数host:连接的mysql主机,如果本机是'localhost'
* 参数port:连接的mysql主机的端口,默认是3306
* 参数user:连接的用户名
* 参数password:连接的密码
* 参数database:数据库的名称
* 参数charset:通信采用的编码方式,推荐使用utf8
conn=pymysql.connect(参数列表)
* 参数host:连接的mysql主机,如果本机是'localhost'
* 参数port:连接的mysql主机的端口,默认是3306
* 参数user:连接的用户名
* 参数password:连接的密码
* 参数database:数据库的名称
* 参数charset:通信采用的编码方式,推荐使用utf8
关闭连接
conn.close()
提交数据
conn.commit()
撤销数据
conn.rollback()
游标对象
游标用来执行sql语句
获取游标
cur = conn.cursor()
使用游标执行sql
cur.execute(sql, 参数)
参数可以是元组, 列表, 字典
返回受影响的行数
获取查询结果集中的一条数据(元组)
cur.fetchont()
(1,'张三')
获取查询结果集中的所有数据(元组)
cur.fetchall()
如果查询了多次, 只打印最后一次的查询结果
((1,'张三'),(2,'李四'))
关闭游标
cur.close()
闭包和装饰器
闭包
定义
在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们把这个使用外部函数变量的内部函数称为闭包。
构成条件
在函数嵌套(函数里面再定义函数)的前提下
内部函数使用了外部函数的变量(还包括外部函数的参数)
外部函数返回了内部函数
示例
# 定义一个外部函数
def func_out(num1):
# 定义一个内部函数
def func_inner(num2):
# 内部函数使用了外部函数的变量(num1)
result = num1 + num2
print("结果是:", result)
# 外部函数返回了内部函数,这里返回的内部函数就是闭包
return func_inner
# 创建闭包实例
f = func_out(1)
# 执行闭包
f(2)
f(3)
运行结果:
3
4
def func_out(num1):
# 定义一个内部函数
def func_inner(num2):
# 内部函数使用了外部函数的变量(num1)
result = num1 + num2
print("结果是:", result)
# 外部函数返回了内部函数,这里返回的内部函数就是闭包
return func_inner
# 创建闭包实例
f = func_out(1)
# 执行闭包
f(2)
f(3)
运行结果:
3
4
作用
闭包可以保存外部函数内的变量,不会随着外部函数调用完而销毁。
可以提高代码的可重用性,不需要再手动定义额外的功能函数。
注意
由于闭包引用了外部函数的变量,则外部函数的变量没有及时释放,消耗内存。
标准格式
# 外部函数
def test1(a):
b = 10
# 内部函数
def test2():
# 内部函数使用了外部函数的变量或者参数
print(a, b)
# 返回内部函数, 这里返回的内部函数就是闭包实例
return test2
def test1(a):
b = 10
# 内部函数
def test2():
# 内部函数使用了外部函数的变量或者参数
print(a, b)
# 返回内部函数, 这里返回的内部函数就是闭包实例
return test2
修改闭包内使用的外部函数变量
使用 nonlocal 关键字在内部函数内修饰变量
类似于global, 但是闭包必须用nonlocal
可复用的计数器
def inc():
x = 0
def inner():
nonlocal x
x += 1
print(x)
return inner
inc1 = inc()
inc2 = inc()
inc1() #1
inc1() #2
inc1() #3
inc2() #1
x = 0
def inner():
nonlocal x
x += 1
print(x)
return inner
inc1 = inc()
inc2 = inc()
inc1() #1
inc1() #2
inc1() #3
inc2() #1
0 条评论
下一页
为你推荐
查看更多