Python高级
垃圾回收
Python中的垃圾回收是以引用计数为主,标记清除和分代收集(隔代回收)为辅。
有三种情况会触发垃圾回收
1. 调用gc.collect(),
2. 当gc模块的计数器达到阀值的时候。
3. 程序退出的时候
gc模块
通过频繁的处理零代链表中的新对象,Python的垃圾收集器将把时间花在更有意义的地方:它处理那些很快就可能变成垃圾的新对象。同时只在很少的时候,当满足阈值的条件,收集器才回去处理那些老变量。
引用计数+1
1.对象被创建,例如a = "hello"
2.对象被引用,例如b=a
3.对象被作为参数,传入到一个函数中,例如func(a)
4.对象作为一个元素,存储在容器中,例如list1=[a,a]
引用计数-1
1.对象的别名被显式销毁,例如del a
2.对象的别名被赋予新的对象,例如a=24
3.一个对象离开它的作用域,例如func函数执行完毕时,func函数中的局部变量(全局变量不会)
4.对象所在的容器被销毁,或从容器中删除对象
gc.disable()  # python 自带的垃圾回收关闭
gc.get_count() : 获取零代,一代,二代的当前值
gc.get_threshold(): 定义的是每代中的最大值   默认的(700,10,10)
当达到最大值则触发:gc.collect()  --->回收不可达的对象
(699,9,0)---》(700,9,0)----》(0,10,0)---》(0,0,1)
(699,5,0)  --->(700,5,0) ----->gc.collect() 检查零代链表并回收   (0,6,0)
总结
1.对象池 intern
2.引用计数  ----》问题:循环引用
3.标记清除
4.隔代回收
gc模块
import gc
gc.collect()
gc.garbage
gc.get_count()
gc.get_threshold()
gc.set_threshold()
gc.set_debug(gc.DEBUG_LEAK)
爬取数据
import urllib.request


response = urllib.request.urlopen("http://www.moojing.com/home/")


print(response)


content = response.read()
content = content.decode("utf-8")
print(content)
正则表达式
import re   
regex
^ 开头
$ 结尾
{n} 就是n位数    {n,} >=n   {n,m}
正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本
[0-9] ~  \d
print(obj.group())
获取匹配的内容
obj=re.search("\d\S\w","89ab")
print(obj)
re 模块
compile
re.compile()  将字符串格式转成一个正则对象
search
re.search(): 表示的是全局查找
pattern = re.compile("BO", re.I)  # 将"B" 一个正则对象
name = "ABOM"
obj = pattern.search(name)  # 看name是否符合pattern正则 ,如果符合则返回一个对象,不能匹配成功则返回一个None值
print(obj)
match
re.match():表示将正则跟字符串的开头位置匹配
pattern = re.compile("A1", re.I)
s = "A1hello"
obj = pattern.match(s)
print(obj)
re模块中search match  [abc]  --->a有没有在lilyc   b有没有在lilyc  c有没有在lilyc
量词
*  >=0
+ >=1 
? 0或者1
加r和不加''r是有区别的
'r'是防止字符转义的 如果路径中出现'\t'的话 不加r的话\t就会被转义 而加了'r'之后'\t'就能保留原有的样子
\ 表示转义
\\ 表示的是"\"
re.compile("\\\w+")  ----> 编译出来的正则对象: \\w+   ---->只能匹配存在一个"\"的字符串
假设: s="\\hello"
re.compile("\\\\\w+") ----> 编译出来的正则对象: \\\w+  ---->只能匹配存在一个"\\"的字符串
太麻烦:
使用元字符串的形式:
在正则表达式编译期间使用元字符串:  re.compile(r"\\\w+")  ----> \\\w+
边界
\b  单词边界
注意
添加r 原生字符  \b在正则中表示单词间隔。
但由于\b在字符串里本身是个转义,代表退格。r是得到字符本身。也就是说\b这两个字符
r"\w+ld\b"  ---》所有以ld结尾的单词
r"\w+ld"  ---》只要单词中有ld,但不是结尾也可以匹配出来
可选值
    re.I(全拼:IGNORECASE): 忽略大小写(括号内是完整写法,下同)
   re.M(全拼:MULTILINE): 多行模式,改变'^'和'$'的行为(参见上图)
    re.S(全拼:DOTALL): 点任意匹配模式,改变'.'的行为
    re.L(全拼:LOCALE): 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
    re.U(全拼:UNICODE): 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
    re.X(全拼:VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。
案例
电话号码  QQ号码
qq=input("请输入QQ号码:")
obj=re.search("^\d?$",qq) # 12
print(obj)
QQ  5-11  不能是0开头
qq=input("请输入QQ号码:")
obj=re.search("^[1-9]\d{4,10}$",qq) # 12
print(obj)
用户名
user_name = input("输入用户名:")
obj = re.search("^.{6}$", user_name)
print(obj)
身份证号码  18位  最后一位可以是x或者数字
^\d{17}[0-9xX]$
用户名:不能是数字开头,可以是数字字母下划线 6-12位
[^0-9] ~ \D  ^[a-zA-Z_]\w{6,11}$
手机号码是: 13 15 18 开头的手机号码
^1[358]\d{9}$
匹配出163的邮箱地址,且@符号之前有4到20位字符,例如hello@163.com
^\w{4,20}@163.com$
所有邮箱
^\w{4,20}@\w{2,}\.(com|cn|net)$