linux基本命令
终端命令格式 command [-options][parameter]
帮助信息 command --help
man command
ls命令
cd命令
-
进入上次所在目录~
进入主目录..
进入上一级目录.
进入当前目录/
算起的路径rm命令
grep命令 grep -n '匹配文本' 匹配文件
sudo命令
ln命令
more命令
关机重启命令
mv命令
mkdir命令的使用
| 管道命令的使用
exit命令:退出登录账户
who命令:查看所有登录用户
cp命令
passwd命令:修改用户密码
zip命令
chmod命令
重定向命令
find命令
which命令:查看命令所在位置的路径
cat命令:查看文件内容、合并文件内容
tar命令:
软件安装与卸载
远程登录 ssh 用户名@ip
远程拷贝 scp命令
vim编辑器使用
IP地址
端口
网络传输方式UDP
socket介绍
UDP网络程序发送接收数据
import socket
import time
"""简易udp聊天器"""
def send_msg(udp_socket):
addr = ('',8080)
content = input("请输入发送内容:")
udp_socket.sendto(content.encode(),addr)
print("发送成功")
def recv_msg(udp_socket):
data,addr = udp_socket.recvfrom(1024,)
content = data.decode()
print(content)
if __name__ == '__main__':
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_socket.bind(('',8080))
send_msg(udp_socket)
time.sleep(2)
recv_msg(udp_socket)
TCP连接
TCP的三次握手和四次挥手
线程
创建线程
# 创建一个简单的线程
import threading
def work1():
print("work1")
def work2():
print("work2")
if __name__ == '__main__':
for i in range(5):
t1 = threading.Thread(target=work1) #参数target=目标函数名
t2 = threading.Thread(target=work2)
t1.start()
t2.start()
t1.join()
给线程传递参数的两种方式
启动线程 t1.start()
查看和获取线程列表
# 查看当前线程
threading.current_thread()
# 获取线程列表
threading.enumerate()
# 获取线程数量
len(threading.enumerate())
守护线程
自定义线程类
import threading
import time
class My_thread(threading.Thread): # 继承自threading.Thread类
def __init__(self, name, age):
"""重写__init__方法,调用父类的__init__方法"""
super(My_thread, self).__init__()
self.name = name
self.age = age
"""重写run方法"""
def run(self):
for i in range(5):
print("my name is %s @ %d years old" % (self.name, self.age))
self.name += "a"
self.age += 1
time.sleep(1)
if __name__ == '__main__':
t1 = My_thread('laowang', 22)
t1.start()
多线程可以共享全局变量,可以通过global修改全局变量,但也带来了问题:多个线程同时修改全局变量,会导致资源竞争的问题。
# join()方法解决这一问题
import threading
num = 0
def work1():
for i in range(10000):
global num
num += 1
def work2():
for i in range(10000):
global num
num += 1
def work3():
for i in range(10000):
global num
num += 1
if __name__ == '__main__':
t1 = threading.Thread(target=work1)
t2 = threading.Thread(target=work2)
t3 = threading.Thread(target=work3)
t1.start()
t2.start()
t3.start()
t1.join()
print(num)
demo:在⼀个进程中开启8 个线程,线程⽤作实现:进程中同⼀个变量i 的做⾃
增运算,每个线程加10000 次。要保证最终变量值为80000 。
from threading import Thread
i = 0
def sum():
for _ in range(10000):
global i
i += 1
if __name__ == '__main__':
for _ in range(8):
t = Thread(target=sum)
t.start()
t.join()
print(i)
互斥锁
首先注意:互斥锁概念是在线程中的
互斥锁的作用:控制多线程同时访问资源
互斥锁创建、加锁和解锁
import threading
import time
lock = threading.Lock() # 创建锁
num = 0
def work1():
for _ in range(10000):
global num
lock.acquire() # 加锁
num += 1
lock.release() # 解锁
print(num)
def work2():
for _ in range(10000):
global num
lock.acquire()
num += 2
lock.release()
print(num)
t1 = threading.Thread(target=work1)
t2 = threading.Thread(target=work2)
t1.start()
t2.start()
while len(threading.enumerate()) != 1:
time.sleep(1)
print("最终结果为num=%s" % num)
死锁产生的原因:两个线程分别占有一部分资源并且同时等待对方的资源。
进程
概念:一个程序运行起来后,代码+所用的资源称之为进程,进程是系统资源分配的基本单位。
进程的三种基本状态:
就绪态:运行的条件都已满足,正在等待cpu执行
执行态:cpu正在执行其功能
等待态:等待某些条件满足,也就是阻塞态。
进程的使用:
进程的创建和启动
import multiprocessing
import time
import os
def work1():
for i in range(10):
print('work1-----')
print(multiprocessing.current_process()) # 查看当前进程
print(multiprocessing.current_process().pid,os.getpid())
time.sleep(1) #查看进程pid的两种方法
if __name__ == '__main__':
p1 = multiprocessing.Process(target=work1) # 创建进程
p1.start() # 启动进程
参数传递与线程传递参数的方法一致
进程间不共享全局变量
实现进程间通信之Queue的使用
import random
import time
from multiprocessing import Process, Queue, current_process
# 写入数据
def write_data(q):
print(current_process().pid)
for value in ['A', 'B', 'C']:
print("put %s to queue" % value)
q.put(value)
time.sleep(random.random())
# 读取数据
def read_data(q):
print(current_process().pid)
while True:
if not q.empty():
data = q.get()
print("get %s from queue" % data)
time.sleep(random.random())
else:
break
if __name__ == '__main__':
# 创建进程
q = Queue()
wp1 = Process(target=write_data, args=(q,))
wp2 = Process(target=write_data, args=(q,))
rp1 = Process(target=read_data, args=(q,))
wp1.start()
wp2.start()
rp1.start()
wp1.join()
进程池
什么是进程池?
可以自动产生进程的容器。
进程池同步、异步执行任务
import multiprocessing
import time
def work():
print('working',multiprocessing.current_process().pid)
time.sleep(0.3)
if __name__ == '__main__':
pool = multiprocessing.Pool(3)
for i in range(10):
# pool.apply(work) # 同步执行任务
pool.apply_async(work) # 异步执行任务
pool.close()
pool.join()
同步和异步的概念:与现实中相反。
进程和线程对比:
迭代器
可迭代对象
本质:所属的类中实现了__iter__
方法的对象
检测方法:isinstance
from collections import Iterable
isinstance(对象,Iterable) #返回True或者False
迭代器及使用方法
自定义迭代器
__iter__
和__next__
方法# 自定义列表
class StudentList(object):
def __init__(self):
self.items = list()
def add_items(self,item):
self.items.append(item)
def __iter__(self):
"""返回一个迭代器"""
studentiterator = StudentIterator(self.items)
return studentiterator
class StudentIterator(object):
def __init__(self,items):
self.items = items
self.current_index = 0
def __iter__(self):
return self
def __next__(self):
if self.current_index < len(self.items):
item = self.items[self.current_index]
self.current_index += 1
return item
else:
raise StopIteration
student = StudentList()
student.add_items('张三')
student.add_items('李四')
student.add_items('王五')
for value in student:
print(value)
生成器
一类特殊的迭代器,可以不需要手动调用next()方法。
利用列表推导式风格创建生成器
G = (x*2 for x in range(5))
print(G)
# G就是一个生成器generator object
next(G) # 使用next()方法获取下一个值
使用函数和yield关键字创建生成器
def fibonacci(n):
a = 0
b = 1
current_index = 0
while current_index < n:
result = a
a,b = b,a+b
current_index += 1
yield result
fib = fibonacci(5)
print(next(fib))
print(next(fib))
print(next(fib))
print(next(fib))
print(next(fib))
print(next(fib))
yield 和 return的对比
使用send()方法启动生成器并传递参数
协程
协程的概念:协程是另外一种实现多任务的方式,比线程占用更小的执行单元。自带CPU上下文。
使用yield实现协程
import time
def work1():
while True:
print("----work1---")
yield
time.sleep(0.5)
def work2():
while True:
print("----work2---")
yield
time.sleep(0.5)
def main():
w1 = work1()
w2 = work2()
while True:
next(w1)
next(w2)
if __name__ == "__main__":
main()
使用greenlet实现协程
from greenlet import greenlet
def work1():
print('work1')
g2.switch()
def work2():
print('work2')
g1.switch()
if __name__ == '__main__':
while True:
g1 = greenlet(work1)
g2 = greenlet(work2)
g1.switch()
使用gevent实现协程
import time
import gevent
# 打补丁,为了让gevent识别自己提供的time.sleep()或者网络请求等耗时操作
from gevent import monkey
monkey.patch_all()
def work1():
for i in range(5):
print('work1')
time.sleep(0.5)
# gevent.sleep(0.5) # 为了使得延时操作能让gevent识别
def work2():
for i in range(5):
print('work2')
time.sleep(0.5)
g1 = gevent.spawn(work1)
g2 = gevent.spawn(work2)
g1.join()
g2.join()
进程、线程、协程对比
####正则
re模块
re.match(正则模型,字符串,flags=0匹配模式)
从起始位置开始匹配,匹配成功返回一个对象,不成功返回None
result.group() 返回匹配成功的字符串
re模块高级用法
import re
result = re.sub(r'\d+','10000','阅读次数:9999次,转发次数:883次,评论次数:3次')
print(result)
# 输出结果为
/usr/bin/python3.6 /home/zorozhang/PycharmProjects/python复习/demo31.py
阅读次数:10000次,转发次数:10000次,评论次数:10000次
Process finished with exit code 0
import re
result = re.split(r': | ',"info:xiaoZhang 33 shandong")
print(result)
# 输出结果
/usr/bin/python3.6 /home/zorozhang/PycharmProjects/python复习/demo31.py
['info:xiaoZhang', '33', 'shandong']
Process finished with exit code 0
匹配单个字符
. 任意一个字符
[] 匹配[]中列举的字符
\d 匹配数字0-9
\D 匹配非数字
\s 匹配空白 空格,tab键
\S 匹配非空白
\w 匹配非特殊字符 a-z A-Z 0-9 _ 汉字
\W 匹配特殊字符
匹配多个字符
* 0或者无限次
+ 1或无限次
? 0或1次
{m} 前一个字符出现m次
{m,n} 前一个字符出现m到n次
匹配开头结尾
^ 匹配字符串开头
匹配分组
| 匹配左右任意一个表达式
(ab) 将括号中字符作为一个分组
\num 引用分组num匹配到的字符串
(?P) 分组起别名
(?P=name) 引用别名为name分组匹配到的字符串
贪婪和非贪婪
贪婪 匹配尽可能多的字符
非贪婪 匹配尽可能少的字符
实现非贪婪匹配 在* ,?,+,{m,n} 后面加?即可
r的作用 阻止转义 表示原生字符串
浏览器访问网站过程
浏览器输入域名—>DNS服务器返回ip地址—>浏览器请求ip地址所在服务器—>服务器返回响应
网址的组成部分
IP地址分为IPv4和IPv6
IP地址由32位二进制构成,分成四段,每段8位二进制。
域名:方便记忆的地址。
DNS作用:域名解析系统,将域名转义成对应的IP地址。
HTTP协议概述
HTTP协议是一种请求–响应协议,超文本传输协议,它是一种应用层协议。
HTTP请求报文:
格式:
请求行 请求方法(GET POST…) 请求路径 协议版本(HTTP/1.1)\r\n
请求头\r\n 常见请求头:host、accept-encoding、referer、accept-language、cookie
空行\r\n
请求体
响应报文格式
响应行 协议版本 状态码 状态信息
响应头 协议名:值 server、date、content-type、location
空行
响应体
200 响应成功 404 Not Found
TCP长连接和短连接
数据库分类:关系型数据库和非关系型数据库
数据类型和约束:
命令行客户端
登录登出数据库
mysql -uroot -p
exit
quit
ctrl+d
数据库操作:
show databases;
select database();
use 数据库名;
create database xxx charset utf8;
drop database 数据库名;
数据库表操作:
show tables;
desc 表名;
create table xxx()
drop table 表名;
show create table 表名;
表字段操作
alter table 表名 add 字段名 类型;
alter table 表名 change 原名 新名 类型和约束
alter table 表名 modify 字段名 类型及约束
alter table drop 字段名;
表数据库操作
select * from 表名;
select 列1,列2 from 表名;
insert into 表名 values (...);
insert into 表名 (列1,...) values (值1,...);
insert into 表名 values(...),(...)...;
insert into 表名(列1,...) values(值1,...),(值1,...)...;
delete from 表名 where 条件;
as 和 distinct关键字
给字段取别名:as 关键字
select id as 序号,name as 名字 from students;
查询结果去除重复行
select distinct 列1,... from 表名;
where 条件查询
> = < >= <= !=或<>
and or not
like
%表示任意多个字符 _表示任意一个字符
in表示非连续范围 between...and...表示连续范围
is null is not null
对查询结果排序
select * from 表名 order by 列1 asc(desc);
分页查询
select * from 表名 where 条件 limit 数据查询的起始下标,显示查询的数量
# 假设每页显示m条数据,当前显示第n页 第n页起始数据下标(n-1)*m m
聚合函数
分组查询
group by 某个字段
分组
group by + group_concat(字段名)
表示按某个字段分组后每个分组中按某一字段的集合
select gender,group_concat(name) from students group by gender;
group by + 聚合函数
连接查询
内连接 A表 inner join B表 on 条件
左连接 A表 left join B表 on 条件
右连接 A表 right join B表 on 条件
自连接 一张表起多个名字inner join
就可以
子查询
select * from students where age > (select avg(age) from students);
查询结果是一行一列select name from classes where id in (select cls_id from students)
查询结果是n行一列外键 Foreign key
添加外键alter table 表名 add constraint 外键约束名 foreign key(列名) references 引用外键表(列名)
删除外键alter table 表名 drop constraint 外键约束名
删除主键alter table 表名 drop constraint 主键约束名
增加主键alter table 表名 add constraint 主键约束名 primary key(列名)
数据库编程
使用pymysql操作mysql
import pymysql
# 创建连接
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='mysql', database='test_1', charset='utf8')
# 获取游标
cursor = conn.cursor()
# 编写sql语句
sql = """select * from xxx;"""
# 执行sql语句 返回受影响的行数
row_count = cursor.execute(sql)
# 返回一行数据
cursor.fetchone()
# 返回所有数据
cursor.fetchall()
cursor.close() # 关闭游标
conn.close() # 关闭连接
参数化列表防止SQL注入
只需要构造参数列表即可。params = [name1,name2,...]
视图
create view 视图名称(v_开头) as select 语句;
show tables;
select * from 视图;
drop view 视图名称;
事务
begin 或者 start transaction;
commit;
rollback;
索引
show index from 表名;
create index 索引名称 on 表名(字段名称 类型(长度));
drop index 索引名称 on 表名;
账户管理
创建账户并授予权限
grant 权限列表 on 数据库 to '用户名'@'访问主机' identified by '密码';
常用权限:create alter drop insert update delete select
修改权限
grant 权限名称 on 数据库 to '账户'@'主机' with grant option;
修改密码
updae user set authentication_string=password('新密码') where user='用户名';
删除账户
drop user '用户名'@'主机';
delete from user where user='用户名';
闭包
概念:在函数的内部再定义一个函数,内部函数用到了外部函数的变量,那么将这个函数以及用到的变量称之为闭包。(本质就是一个嵌套定义的函数)
闭包语法格式
def func(func):
def wrapper(num):
result = inner(num)
return result
return wrapper
装饰器的作用和概念
全局解释器锁GIL
深拷贝和浅拷贝
import循环导入问题:解决方法:什么时候用就什么时候导入
property属性
使用@property
进行装饰后,可以使调用方法就像调用属性一样,不需要加括号
注意:
新式类的三种@property装饰器
@property
@属性.setter
传值@属性.deleter
del 删除属性时自动调用class Goods:
"""python3中默认继承object类
以python2、3执行此程序的结果不同,因为只有在python3中才有@xxx.setter @xxx.deleter
"""
@property
def price(self):
print('@property')
@price.setter
def price(self, value):
print('@price.setter')
@price.deleter
def price(self):
print('@price.deleter')
# ############### 调用 ###############
obj = Goods()
obj.price # 自动执行 @property 修饰的 price 方法,并获取方法的返回值
obj.price = 123 # 自动执行 @price.setter 修饰的 price 方法,并将 123 赋值给方法的参数
del obj.price # 自动执行 @price.deleter 修饰的 price 方法
类属性方式,property方法中的四个参数get_
、set_
、del_
、description
class Goods(object):
def __init__(self):
# 原价
self.original_price = 100
# 折扣
self.discount = 0.8
def get_price(self):
# 实际价格 = 原价 * 折扣
new_price = self.original_price * self.discount
return new_price
def set_price(self, value):
self.original_price = value
def del_price(self):
del self.original_price
PRICE = property(get_price, set_price, del_price, '价格属性描述...')
obj = Goods()
obj.PRICE # 获取商品价格
obj.PRICE = 200 # 修改商品原价
del obj.PRICE # 删除商品原价
魔法方法和属性
__doc__
表示类的描述信息__module__
表示当前操作对象的在哪个模块__class__
表示当前操作的对象的类是什么__init__
初始化方法__del__
当对象在内存中被释放时,自动触发执行__call__
对象后面加括号自动触发执行__dict__
返回类或对象的所有属性__str__
打印对象时(print(obj)
)输出该方法的返回值,所以该方法必须有返回值__getitem__
、__setitem__
、__delitem__
用于索引操作,如字典。分别表示获取、设置、删除数据with上下文管理器
__enter__()
和__exit__()
方法的对象都可以称之为上下文管理器,都可以使用with关键字class File(object):
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def __enter__(self):
self.f = open(self.filename, self.mode)
return self.f
def __exit__(self, exc_type, exc_val, exc_tb):
self.f.close()
if __name__ == '__main__':
with File('demo32.py', 'r') as f:
m = f.read()
print(m)
使用@contextlib
装饰器对函数实现上下文管理器
from contextlib import contextmanager
@contextmanager
def my_open(file,mode):
f = open(file,mode)
yield f
f.close()
if __name__ == '__main__':
with my_open('demo32.py','r') as f:
m = f.read()
print(m)