python的特点
- 简单
- 边编译边运行
- 高级 ------- 不注重底层源码
- 面向对象 -------- 既支持面向对象也支持面向过程
- 可扩展 ----- 扩展的模块
- 免费和开源
- 可移植 ------python可以应用在不同的平台上
- 丰富的库 ------python拥有很多第三方库,非常的丰富
- 可嵌入性 ----- python可以嵌入到C、C++中,为其提供 脚本的功能
前期用记事本编写python运行方法
- 打开cmd用cd切换到xxx.py文件所在文件夹输入python xxx.py(可用tab键补)
- 在xxx.py文件所在文件夹的文件栏直接输入cmd
- 直接将文件拖入cmd窗口
注释方法
- 单行注释# xxxx
- 多行注释""“xxxxxx”""
定义变量
python为弱语言类型,直接a=3,无需特意申明变量类型
Type(a) 返回变量的数据类型
1.变量名称只能由有效字符(大小写字母,数字,下划线)组成(name+ 报错语法错误)
2.不能以数字开头
3.不能是关键字或者是保留字
4.变量命名尽量有意义(name age sex )
1字节 byte 、boolean
2字节 short 、char
4字节 int 、float
8字节 long 、double
基本数据类型
数值型
整型 int
浮点型 float(无double)
虚数(复数) i 不常用
布尔型
Flase or True (要大些)
字符型
a=‘x’
转义符 \ (和别的语言一样)
ord() 查看字符所对应得编码
chr() 查看编码所对应得字符
复合数据类型
如 字典 元组 序列 集合。。。
输入输出
输入
x=input(“可在里面血东西”)
注意默认得到的是字符型
如果要得到int型可以使用x=int(intput())
如果要一次性输入多个数
a,b,c=eval(input())
数据的类型转换
int(“字符型”) 将字符型转换成Int
flaot(“字符串”) 将字符型转换成float型
str(“其他类型”) 将其他类型转换成字符型
输出
一般输出
print(“输出东西”)
输出字符串+数字
使用占位符
- print(“数字是%s和%s”%(x,y))
使用类型转换并用加法连接 - print(“数字是”+str(x)+“和”+str(y))
- print(“数字是”,x,y)
- print(“数字是”.format(x))
注意:不能直接输出print(“字符串”+数值型)
保留小数位后几位
输出保留2位小数
print("%.2f"%x)
常见运算符
算术运算符
符号 | 运算 |
---|---|
+ | 加法(连接字符串) |
- | 减法 |
= | 赋值运算 |
% | 取余 |
* | 乘法 |
* * | 次方 |
/ | 除法(得到float型) |
// | 整除(得到整型向下取整和别的语言int型一样) |
比较运算符
符号 | 运算 |
---|---|
> | 大于 |
< | 小于 |
== | 等于 |
<= | 小于等于 |
>= | 大于等于 |
!= | 不等 |
逻辑运算符
符号 | 运算 |
---|---|
and | 逻辑与 |
or | 逻辑或 |
not | 逻辑非 |
赋值运算符
符号 | 运算 |
---|---|
+= | 加等(a+=b实际上就是a=a+b) |
-= | 减等 |
/= | 除等 |
//= | 整除等 |
*= | 乘等 |
**= | 次方 |
%= | 取模等 |
注意没有++x,x++之类的运算了
选择结构
单分支
if a>b:
(\t or space)print(a)
缩减距离一定要相等,缩减的地方即为判断语句的作用范围
双分支
if a>b:
(\t or space)print(a)
else:
(\t or space)print(b)
多分枝
if a>90:
(\t or space)print(“perfect”)
elif a>60:
(\t or space)print(“good”)
else:
(\t or space)print(“bad”)
elif就是别的语言的else if
循环结构
while
打印一到一百
a=1
while a<=100:
(\t or space)print(“a”)
(\t or space)a+=1
和if一样用缩进来确定循环体
for
打印一到九十九
for i in range(1,100)
(\t or space)print(i)
此写法等价于别的语言的for(int i=1;i<100;i++)
range里面为前闭后开
range(int,int,int)
第一个int表示从那个数开始,
第二个int表示到那个数的前一个数结束,
第三个int表示数字如何将如何改变,可以为负数
for i in range(100,0,-1)
(\t or space)print(i)
打印100到1
range(int,int)
从一个数到后面的数减一,为前闭后开,等价于range(int,int,1)
range(int)
从零到此数减一,等价于range(0,int),range(0,int,1)
for语句也可以判断某个值是否在容器内
break
跳出此次循环,只跳出一层
continue
跳过此次循环,直接进行下一次循环
容器
列表
线性表(常见的线性表:链表 数组 栈 队列)
python没有数组
列表钟的元素不需要为统一数据类型
定义列表
ls=[1,2,3]
ls=list([1,2,3])通过全局函数list()定义
访问元素
通过角标来访问例如 ls[0]
角标可以为负数
遍历元素
for i in ls:
print(i)
或者
i=0
while i<len(ls):
print(ls[i])
i+=1
常用方法
-
append() -------- 像列表的尾部追加元素
-
insert (index,object) ---------- 在列表里指定的位置添加元素
-
sort() ---------- 列表元素进行排序,整形(从小到大的顺序)
-
index() --------- 查看列表里某一个元素的下标(如果有多个元素,查找的角标是第一个出现的位置)如果没有会报错
-
reverse() --------- 将列表元素进行翻转
-
remove() -------- 通过元素在列表中删除元素,如果元素不存在会报错
-
count()---------- 统计元素在列表中出现次数
-
clear() --------清除列表
-
copy()------- 浅拷贝 不等价于 =
-
extend()------ 合并列表
-
pop() ------- 从列表的尾部删除元素,并且返回删除掉的元素,pop(i)------删除角标为i处的元
集合
为哈希结构,里面元素自动排好序
定义集合
- s={1,2,3}
- s=set({1,2,3})
集合里的元素不能重合
常用方法
clear() -------------------- 清除元素
copy()----------------浅拷贝
remove()------------删除元素
add() ---------------- 向集合添加元素,如果添加的元素是重复的,不能够添加
difference() --------- 差集
intersection()--------- 交集
union() -------------------并集
update() -------- 更新集合,合并集合
discard()-------- 移除元素,如果元素不存在,不做任何操作
元组
定义元组
- t = (1,2,3)
- t = tuple((元素))
元组是有序,通过下标来获取元素 下标可以是负数 但是不可以通过下标更改,但是元组内的元素是可变的
a = (1) ,a的类型是int型
a=(1,),a的类型是元组
字典
以键值对存在 Key value
定义字典
- d = {“name”:“zhangsan”,“age”:“18”}
- d = dict({“name”:“zhangsan”,“age”:“18”})
访问元素
d[“name”]
通过key获取对应value ------ d[“key”],如果没有Key 会抛出异常
q[“name”]=newValue---------改变元素
q[“newName”]=value--------插入元素
常用方法
clear()-------清空
copy()-------浅拷贝
get() -------- 通过key获取value ,如果没有Key,返回的是none
keys() ------------ 返回字典里所有的Key值
values () ------------------ 返回的所有的值
setdefault ----------- 设置的默认值
items() -------- 返回所有的键值对
pop(key) ------------- 通过key来移除键值对,返回的是key所对应的value,删除字典里没有的key
会抛出异常
popitem() ---------- 移除键值对,遵循LIFO,返回值删除的键值对
遍历字典
- for k in d:
print(k,d.get(k)/d[k]) - for k in d.key():
print(k,d[k]) - for k,v in d.items()
print(k,v)
字符串
定义字符串
定义字符串可以用单引号,双引号,三引号。
常用方法
capitalize() ------------- 格式化字符串,将首字母大写
center() ---------------设置字符串居中
count()----------------- 统计字符的个数
endswith()------------判断字符是不是xxxxx为结尾
startswith()------------判断字符串是不是以xxxxx为开头
index() ------------- 查找字符或者符串在字符串第一次出现的位置,如果查找的字符或者字符串没有会抛出异常
rindex()--------从右往左查找,查找字符或者符串在字符串第一次出现的位置,如果查找的字符或
者字符串没有会抛出异常
find()--------查找字符或者符串在字符串第一次出现的位置,如果不存在返回是-1
rfind()-----------从右往左查找,查找字符或者符串在字符串第一次出现的位置,如果不存在返回是-1
encode() -------- Python3 将字符串转换为字节 ,decode() --------将字节转换为字符串
islower() -------- 判断字符串是否都是小写字母isupper()---------判断字符串是否都是大写字母
istitle()----------判断字符串是否是标题
title()--------- 将字符串转换为标题
isspace() ------- 判断字符串是否为空格位
isdigit()------- 判断字符串是否为数字
isalnum()-----判断字符串是否为数字,判断是否有有效字符
isalpha()------ 判断字符串是否都是字母
strip() ------- 去掉字符串两侧空格
rstrip()--------去掉右侧的空格
lstrip()---------去掉左侧的空格
replace(“原字符串”,“新字符串”)------替换字符串
rjust()---------------返回一个右对齐字符串
ljust()---------------返回一个左对齐字符串
split(“符号”) -----------分割字符串,返回结果的是列表
join()--------- 按照特定的符号将可迭代的容器拼接成字符串
切片操作
容器可进行切片操作
格式
- object[start_index:end_index:step]--------完整切片格式.start_index为起始索引,end_index为结束的索引,step为步长,也为前闭后开,从start_index到end_index-1.step正负都可以。
- object[start_index:end_index]------从start_index开始,切割到end_index-0结束,方向是从左往右
- object[start_index:]------从start开始,切割到终点,方向是从左往右
- object[start_index]-------访问第start_index元素
- object[:]-------全部访问
- object[::]-------全部访问
- object[::-1]--------反向全部访问
- object[:end_index]--------从第一元素访问到end_index-1
容器索引值
和别的语言一样索引从0开始但是python还有负索引
如list=[0,1,2,3]
- 正索引------list[0]==0,list[1]==1,list[2]==2,list[3]==3
- 负索引------ist[-1]==3,list[-2]==2,list[-3]==1,list[-4]==0
函数
函数的定义
def 函数名(定义参数(可以没有参数))
(缩进)函数体
(缩进)return(可以没有返回值)
注意:函数可以返回多个值,但是返回的结果实则是元组tuple
函数的分类
以参数
有参函数
无参函数
以返回值
有返回值函数
无返回值函数
定义者分
系统
第三方
全局变量和局部变量
全局变量
在py文件里面的变量就是全局变量,代码运行的时候,变量始终有效
函数的内部是可以访问全局变量,但是不能改变(操作)全局变量
可以用 global (全局变量)来改变
局部变量
定义在函数内部的变量,只能在函数内部有效。在函数运行结束就释放变量的空间
函数的参数
位置参数
def fun(x)…
fun(x)
默认值参数
def fun(x=0)…
fun()-------如果没有传参,函数的x就会为默认值0
fun(3)-------函数的x为传过来参数3
注意:默认值参数应该写在必选参数的后面,别的语言也一样
可变参数
def fun(*x)…
fun(1,2,3)----x接受的就是以1,2,3组成的列表
fun(*list)-----表示list的所有元素作为可变参数传递给了函数
关键字参数
def fun(x,**y)
fun(x)------函数可接收到x和一空集合
fun(x,name=“zhangsan”)------函数可接收到x,已经以name:zhangsan组成的键值对
fun(x,name=“zhangsan”,age=“18”,…)后面的内容可以随意加但必须是a=b的形式
命名关键字参数
def fun(x,*,y)
y为键的键值对一定要定义
只能写成fun(x,y=z)的形式
匿名函数
没有名字的函数
匿名函数的定义
lambda 参数(可以没有) : 返回值
三数之和
sum = lambda a,b,c : a+b+c
print(sum(2,3,4))
需要用变量引用匿名函数
表达式分支
max = lambda x,y : x if x > y else y
print(lmax(5,3))
这种写法就有点像别的语言的三元运算符x>y?x:y
作为一个参数传递
下面的程序运行后可以把x-y打印出来
def fun(a,b,func):
print("a",a)
print("b",b)
print("a-b",func(a,b))
fun(1,2,lambda x,y:x-y)
作为函数的返回值
def fun(a,b):
return lambda c:a+b+c
funa=fun(2,3)
#funa此时为函数lambda c:2+3+c
print(funa(4))
偏函数
在python中,我们需要把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,就可以用到偏函数
需要应用模块functools
就比如说int()可以把字符串转成十进制的数字,英文int()默认base值为10可以使用偏函数把base改成2,函数就可以把数字转为二进制的数
import functools
int3 =functools.partial(int,base=2)
print(int3("101"))
如果写成匿名函数就是
int3=lambda x:int(x,base=2)
print(int3("101"))
全局函数
https://docs.python.org/3/library/functions.html#abs
在这个里面直接去看
常见内置模块
模块分类
- 内置模块(如random,math等)
- 第三方文件,可以在线安装(python -m pip install)和离线安装(python install setup.py)
模块导入
- import 模块名
- import 模块名 as 别名
- from 包 import 模块的名称
random模块
用来生成随机数(伪随机)
常用方法
randint() --------- 产生随机整数[m,n](注意左闭右闭)
random() --------------产生0-1的随机数[0,1)
uniform() ------------- 产生正态分布的随机数(用于数学研究)
randrange() ------ 产生一个范围内的随机数
choices() ---------- 用在序列(容器)(有序的序列)随机筛取一个元素(选取数之后会被删除)
math模块
数学运算模块
常用方法
ceil ------------- 向上取整
floor ----------- 向下取整
e ------------ 属性 自然常数fabs ----------- 求绝对值 等价 abs() 全局函数
fmod ----------- 求模运算
isnan -------- 判断是不是数字 (是数字返回 false nan -----not a number)
isfinite ----- 判断是不是无限
pi ----------- 圆周率
pow ------------- 幂次方
sqrt ---------- 平方根
os模块
操作系统文件
常用方法
os.system(“cls”)--------------------清屏
os.system(“pause”)----------------暂停
abspath(相对路径) ----------------- 返回的此python所对应的绝对路径
altsep ------------------ 返回的python中的分隔符
basename ------------ 文件名称
dirname ----------- 文件目录
exists ---------------- 判断文件或者目录是否存在
getctime -------- 获取时间(创建时间)
getmtime ------------ 修改时间
getsize ------------ 获取文件的大小,单位是字节
isdir-------------- 判断path是否是目录(文件夹)
isfile-------------------判断path是否是文件
isabs ------------- 判断是不是绝对路径islink ------- 判断是不是链接
ismount ---------- 判断是不是挂载文件
join -------------- 拼接路径
sep ----------- 路径分隔符
split ----------分割路径
relpath ------------- 返回的真正的路径和abspath一样
搜索硬盘中的文件夹和文件
import os
from os import path
def scanf(url):
files=os.listdir(url)
for file in files:
abs_file=url+"\\"+file;
if(os.path.isdir(abs_file)):
print(abs_file)
scanf(abs_file)
else:
print(file)
scanf("D:\\")
这样就可以打印出D盘的文件(有些文件会拒绝访问)
sys模块
常用方法
api_version -------------- 属性 获取python内部的版本号
argv() --------- 接收脚本参数 (把输入的参数看成列表)
copyright ------------ 输出cpython版本号
exit ---------- 退出系统
getdefaultencoding()-----------获取的默认编码,python3默认编码是utf-8
getfilesystemencoding()-------- 获取文件系统的默认编程,默认utf-8
getrecursionlimit()------- 获取python对递归的限制层数
setrecursionlimit() -------------重新设置递归的限制的层数
getrefcount(对象)--------- 获取对象的引用计数
getwindowsversion() -------- 获取当前窗口的版本信息
version ------------- 获取版本信息
加密算法
hashlib库
哈希算法
使用步骤:
创建算法对象(md5 sha256),返回的是算法对象
md5 = hashlib.md5(str)
如果不做盐值混淆程序很容易被破解出来,使用盐值可以增强安全性
盐值混淆
md5.update(str)
盐值越复杂,加密的安全性就越高
hmac库
也是哈希算法
new(要加密的字符串,参数盐值,加密算法)
uuid 模块
一般会用在文件上传或者文件备份的时候,产生一个永不重复的字符串
uuid.uuid4().hex
时间模块
time模块
asctime() ------------ 获取当前时间
ctime()------ 获取当前时间
localtime()------ 获取的本地时间,返回的是对象
sleep()-------- 表示休眠的时间,单位秒
time()---------------- 获取当前系统的时间戳,单位也是秒
strftime()------- 将时间对象格式化成字符串
strptime()------将一个特定的时间字符串转换为时间对象
datetime模块
Time模块的补充
now() ------------获取当前的时间
IO模块
要用于输入和输出
操作IO流
open(文本字符或字节,打开文件的方式)
读取文件
f = open("path","r")
# f = open("path","rb")
f.read()
f.close()
写入文件
覆盖写入
f = open("path","w")
# f = open("path","wb")
f.read()
f.close()
添加写入
f = open("path","a")
#f = open("path","ab")
f.read()
f.close()
复制文件
import os
def copy_file(src,dest):
base=os.path.basename(src)
base=base[base.rfind(".")::]
dest=dest+"\\temp"+base
f=open(src,"rb")
f2=open(dest,"wb")
#f2.write(f.read())
while True:
data=f.read(1024*1024)
if(data==b""):
#meet empty byte
print("end")
break;
else:
f2.write(data)
f2.close()
f.close()
copy_file('F:\\VC++6.0\\合成 1_1.mp4','F:\\idea')
对象序列化
将抽象的字典 列表 元组 集合等对象的概念转换真正的字符或者字节数据
pickle模块
dumps -------------- 将对象序列化为字节数据 .dat
loads -------------- 将数据反序列化为对象
dump --------------将对象序列化为字节数据 ,并且保存到file
load -------------- 将数据反序列化为对象
import os
import pickle
ls=[3,2,3,4,5]
pickle.dump(ls,open("F:\\VC++6.0\\a.dat","wb"))
print(pickle.load(open("F:\\VC++6.0
json模块
Python2只能操作字典对象
dumps -------------- 将对象序列化为字节数据 .dat
loads -------------- 将数据反序列化为对象
dump --------------将对象序列化为字节数据 ,并且保存到file
load -------------- 将数据反序列化为对象
面向对象
创建类
- class User: 旧时类
- class User():新类
初始化
重写 init(self): 函数来实现,可以理解为别的函数中的构造函数,其中self就类似于别的语言的this表示该对象
class User(object):
__init__(self,name,age):
self.name=name
self.age=age
封装
私有
设置私有可以在参数前加上’__‘ 形如self.__name,这样外界无法直接访问到需要写set和get的方法,通过函数来改变和获取变量。
property()
类似于c#写属性,通过property()实现直接属性的直接调用
class User(object):
def __init__(self, name, age, gender, tel):
self.__name = name
self.__age = age
self.__gender = gender
self.__tel = tel
def __str__(self):
return "name=" + self.__name
def get_name(self):
return self.__name
def set_name(self, username):
self.__name = username
def get_age(self):
return self.__age
def set_age(self, age):
self.__age = age
name = property(get_name, set_name)
age = property(get_age, set_age)
if __name__ == '__main__':
u = User("trump", 75, "男", "110")
print(u)
u.name = "biden"
print(u)
装饰器
@property为get,@name.setter为set
class User(object):
def __init__(self, name, age, gender, tel):
self.__name = name
self.__age = age
self.__gender = gender
self.__tel = tel
def __str__(self):
return "name=" + self.__name
@property
def name(self):
return self.__name
@name.setter
def name(self, username):
self.__name = username
if __name__ == '__main__':
u = User("trump", 75, "男", "110")
print(u)
u.name = "biden"
print(u)
继承
子类可以继承父类非私有的属性和方法
子类可以重新父类的方法(override)
class RichMan(object):
def __init__(self):
self.name="JackMa"
self.proprety="蚂蚁金服"
def say1():
print("我对钱不感兴趣")
def say2():
print("996是福报")
class Son(RichMan):
def say1():
print("加油打工人")
s=Son
s.say1()
s.say2()
打印出来的为加油打工人和996是福报 对say1进行了重写
注意:python里面是没有重载,但是可以实现重载-----通过装饰器
super
调用父类的方法
class RichMan(object):
def __init__(self):
self.name="JackMa"
self.proprety="蚂蚁金服"
def say1(self):
print("我对钱不感兴趣")
def say2(self):
print("996是福报")
class Son(RichMan):
def say1(self):
print("加油打工人")
super().say1()
s=Son()
s.say1()
多态
python是弱数据语言所以不重要
异常
异常:正常的情况,运行程序的过程中出现问题,不一定是错误
处理异常
try except
try:
num = int(input("请你输入一个数:"))
result = num + 10
#except Exception as e:
except ValueError as e:
print("出异常")
print("在这里处理异常,出现的异常是",e)
num = int(input("输入的格式是数字:"))
result = num + 10
finally
try:
num = int(input("请你输入一个数:"))
result = num + 10
#except Exception as e:
except ValueError as e:
print("出异常")
print("在这里处理异常,出现的异常是",e)
num = int(input("输入的格式是数字:"))
result = num + 10
需要注意:函数中,如果return后面存在finally,那么代码并不会直接返回,而是需要执行finally,再执行返回
def demo(msg):
try:
msg+=10
print("hello world")
return "A"
except Exception as e:
print("处理异常")
return "B"
finally:
print("释放资源")
return "C"
print(demo("nsml"))
print(demo(233))
结果是
处理异常
释放资源
C
hello world
释放资源
C
自定义异常
class MyException(Exception):
def __init__(self,msg):
Exception.__init__(self,msg)
def login(username,password):
if username == None or username.strip() == "":
#raise关键字 抛出异常
raise MyException("对不起,用户名不能为空")
if password == None or password.strip() == "":
raise MyException("对不起,密码不能为空")
if __name__ == '__main__':
try:
login("张三", None)
except Exception as e:
print(e)
python的高级编程
包和模块
常见的导包方式:
- import package.moudle
- import package.moudle as 别名
- from package import moudle
- from package1,package2,package3… import moudle
- from package import *
判断变量
- is判断两个变量的内存地址
- ==判断两个变量的值是否相等
python提供小整型缓存区(-5 ~ 256)在数据区
深拷贝和浅拷贝
引用赋值 (=)
数据存在栈里面的复制
就是差不多给原有的容器换了一个名字本质是差不多。
ls=[0,[1,2],1,2]
ls1=ls
ls1[3]=1
print(ls is ls1)#true
print(ls)#[0, [1, 2], 1, 1]
print(ls1)#[0, [1, 2], 1, 1]
浅拷贝
ls=[0,[1,2],1,2]
ls1=ls.copy()
print(ls is ls1)#false
print(ls[1] is ls1[1])#true
ls1[1][1]=3
print(ls)#[0, [1, 3], 1, 1]
print(ls1)#[0, [1, 3], 1, 1]
相当于只拷贝了一层
最外边的一层的地址改变了,内部的地址全都没改变更改内部容器,所有浅拷贝的内部都会改变
深拷贝
import copy
ls=[0,[1,2],1,2]
ls1=copy.deepcopy(ls)
print(ls is ls1)#false
print(ls[1] is ls1[1])#false
ls1[1][1]=3
print(ls)#[0, [1, 2], 1, 1]
print(ls1)#[0, [1, 3], 1, 1]
深拷贝每一层都是新的地址
生成器
列表推导式
可以快速得到一个你想要得列表
ls1 = [x for x in range(101)]得到里面1到100的列表
列表生成器
ls1 = (x for x in range(101))
next(res) 相当于指针,不会回退,直到抛出异常
yield关键字
会将函数的返回值返回为一个生成器(把所有的返回值组成生成器)
迭代器
迭代是一种访问容器的方式
判断是否为迭代对象
from collections.abc import Iterable
isinstance(xx,Iterable)
判断是否为迭代器
from collections.abc import Iterator
isinstance(xx,Iterator)
转换成迭代器
iter(iterable)
闭包(closure)
闭包是一种现象,弱数据类型语言特有的
概念:在函数的内部可以去调用其他函数的变量的现象(函数的变量是局部变量,作用域是函数本
身)函数包裹着函数的现象就是闭包
def outer():
print("这是一个闭包函数")
a = 10
def inner():
print("这是函数里面的代码")
b = 20
print(a + b)
#return inner()
return inner
res = outer()
print(res)
#指向函数
res()
调用函数的本质压栈的过程
python中不建议使用闭包,因为会让函数常驻到内存,导致垃圾不能及时释放,局部变量变成全局
变量。用在装饰器
装饰器的使用
什么是装饰器?
就是一个闭包的函数的使用,它能够@闭包函数的名称装饰一个原有的函数,使得原本的函数功能
更加完善
如何定义一个装饰器?
1.定义闭包函数,闭包函数有一个默认的参数,引用,引用的就是所要装饰的函数
2.需要在闭包里面的函数调用引用(fn()),在调用之前的代码会被在装饰的函数之前执行,之后的
代码在被装饰的函数之后执行
有参
def out(fun):
def write():
print("initiate write")
fun()
print("initiate end")
return write
@out
def execution():
print("233")
execution()
有参
def out(fun):
def write():
print("initiate write")
fun()
print("initiate end")
return write
@out
def execution():
print("233")
execution()
默认值参数
def out(fun):
def write(a="112"):
print("initiate write")
fun(a)
print("initiate end")
return write
@out
def execution(a=""):
print(a)
execution("233")
execution()
关键字参数
def out(fun):
def write(a,**b):
print("initiate write")
fun(a,b)
print("initiate end")
return write
@out
def execution(a,b):
print(a,b)
execution(1,name="zhanghui")
命名关键字参数
def out(fun):
def write(a,*,b):
print("initiate write")
fun(a,b)
print("initiate end")
return write
@out
def execution(a,b):
print(a,b)
execution(1,b="zhanghui")
有返回值参数
def out(fun):
def write(a,*,b):
print("initiate write")
fun(a,b)
print("initiate end")
return b
return write
@out
def execution(a,b):
print("execution")
print(execution(1,b="nyu"))
正则表达式
import re
match() ------------ 从头开始匹配
元字符
\d -------------------- 匹配数字
. --------------------- 匹配的是任意符号(除了\n)
\w ---------------- 匹配所有的有效符号(大小写字母,数字,下划线,各国语言符号)
\s ------------------- 匹配的是空白位(空格 \t(四个空格))
^ ------------------- 以xxxx开头 例如:以1开头 ^1
$ ------------------ 以xxx结尾
[] ------------------- 列举 [0123456789]等价于\d [a-z] [A-Z] [A-Za-z]
反义符
\D -------------- 不是数字
\W ------------ 特殊符号
\S --------------- 非空白位
^------------------- 列举反义
位数
.* ----------------- 表示的是匹配任意位(可以0位,可以是1位…)
±------------------表示的是至少一位(最少就要一位,可以n位)
?----------------- 0位或者是1位
{n,} ----------------- 至少n位
{n,m} ------------------ 表示n-m范围
分组(group)
在正则表达式里面,使用()将正则包裹起来,会形成正则进行二次筛选
去掉html里面的标签
r"</?.+?>"
爬虫
爬虫,又叫做网络爬虫,按照一定的规律,去抓取万维网上的信息的一个程序
爬虫的目的:采集数据
爬虫的分类:
- 通用的网络爬虫(检索引擎(百度))遵循robots协议
- 聚焦网络爬虫
- 增量式网络爬虫
- 累计式爬虫
- 深层网络爬虫(暗网)