python025

re模块
re模块是pyhon中的提供的一套关于处理正则表达式的模块.核心功能有四个:
1.findall 查找所有.返回list
import re
lst=re.findall("m","mai le fo len,mai ni mei!")
print(lst) #结果:['m', 'm', 'm']
lst=re.findall(r"\d+","5点之前.你要给我5000万")
print(lst) 结果:['5', '5000']
2.search会进行匹配.但是如果匹配到了第一个结果.就会返回这个结果.如果匹配不上search返回的就是None
ret=re.search(r"\d","5点之前.你要给我5000万").group()
print(ret) #结果:5
3.match 只能从字符串的开头进行匹配
ret=re.match("a","abc").group()
print(ret) #结果:a
4.finditer和findall差不多.只不过这时返回的是迭代器
it=re.finditer("m","mai le fo len,mai ni mei!")
for el in it:
print(el.group()) #依然需要分组
5.其他操作
ret=re.split('[ab]','qwwerafjbcd')
print(ret) #结果:['qwwer', 'fj', 'cd']
ret=re.sub(r"\d+","__sb__","alex250taibai250ritian250wusir250")
print(ret) 把字符串中的数字换成__sb__
ret=re.subn(r"\d+","__sb__","alex250taibai250ritian250wusir250")
print(ret) #('alex__sb__taibai__sb__ritian__sb__wusir__sb__', 4) (替换的结果,替换了多少次)
obj=re.compile(r'\d{3}')
ret=obj.search('abc123eeee')
print(ret.group()) #结果:123

爬虫重点:
obj=re.compile(r'(?P<id>)\d+)(?P<name>e+)') #从正则表达式匹配的内容每个组起名字
ret=obj.search("abc123eeee") 搜索
print(ret.group()) #结果:123eeee
print(ret.group("id")) #结果:123
print(ret.group("name")) #结果:eeee
6.两个坑
注意:在re模块中和我们在线测试工具中的结果可能是不一样的
import re
ret=re.findall("www.(baidu|oldboy).com","www.oldboy.com")
print(ret) #结果['oldboy'] 这是因为findall会先把优先匹配的结果组里内容返回,如果想要匹配结果,取消权限即可
ret=re.findall("www.(?:baidu|oldboy).com","www.oldboy.com")
print(ret) #结果:['www.oldboy.com']
split里也有一个坑
ret=re.split("\d+","eva3agon4yuan")
print(ret) #结果:['eva', 'agon', 'yuan']
ret=re.split("(\d+)","eva3agon4yuan")
print(ret) #结果:['eva', '3', 'agon', '4', 'yuan']
在匹配部分加上()之后所切出的结果是不同的
没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项
这个在某些需要保留匹配的部分的使用过程是非常重要的
import re
from urllib.request import urlopen
import ssl
ssl.Create_default_https_context=ssl._create_unverified_context()
def getPage(url):
response=urlopen(url)
return response.read().decode("utf-8")
def parsePage(s):
ret=re.findall(
'<div class="item">.*?<div class="pic">.*?<em .*?>(?P<id>\d+).*? '
'<span class="title">(?P<title>.*?)</span>'
'.*?<span class="rating_num" .*?>(?P<rating_num>.*?)</span>.*?<span> '
'(?P<comment_num>.*?)评价</span>',s, re.S)
return ret
def main(num):
url='https://movie.douban.com/top250?start=%s&filter=' % num
response_html=getPage(url)
ret=parsePage(response_html)
print(ret)
count=0
for i in range(10):
main(count)
count+=25
此时利用的就是分组之后.匹配成功后获取到的是分组后的结果.(?P<id>\d+)此时当前组所匹配的数据就会被分组到id内.此时程序可以改写成:
import ssl
import re
from urllib.request import urlopen # ⼲干掉数字签名证书
# ssl._create_default_https_context = ssl._create_unverified_context
def getPage(url):
response = urlopen(url)
return response.read().decode('utf-8')
def parsePage(s): com = re.compile(
'<div class="item">.*?<div class="pic">.*?<em .*?>(?P<id>\d+).*? <span class="title">(?P<title>.*?)</span>' '.*?<span class="rating_num" .*?>(?P<rating_num>.*?)</span>.*? <span>(?P<comment_num>.*?)评价</span>', re.S) ret = com.finditer(s) for i in ret: yield { "id": i.group("id"), "title": i.group("title"), "rating_num": i.group("rating_num"), "comment_num": i.group("comment_num"), }
def main(num):
url = 'https://movie.douban.com/top250?start=%s&filter=' % num
response_html = getPage(url)
ret = parsePage(response_html)
# print(ret)
f = open("move_info7", "a", encoding="utf8")
for obj in ret:
print(obj)
data = str(obj)
f.write(data + "\n")
count = 0
for i in range(10):
main(count)
count += 25
模块
1.模块
2.import
3.from xxx import xxx
一.模块
模块就是一个包含了python定义和声明文件,文件名就是模块的名字加上.py后缀.换句话说我们目前写的所有的py文件都可以看成是一个模块但是我们import加载的模块一共分成四个通用类别:
1.使用python编写的py文件
2.已被变异为共享库或者DLL或者c++的扩展
3.包好一组模块的包
4.使用c编写并连接到python解释器的内置模块
为什么 要使用模块?为了我们写的代码可以重用.不至于把所有的代码都写在一个问件内.当项目规模比较小的时候.完全可以使用.
换句话说我们目前写的所有的py文件都可以看成是一个模块但是我们import加载的模块一共就分为四个通用类别.
如何使用模块?我们已经用过很多模块了.导入模块有两种方式
1.import模块
2.from xxx import xxx
二.首先.我们先看看import,在使用import的时候,我们先创建yitian.py在该文件中创建一些武林前辈和一些打斗场景,代码如下.
print("⽚头曲. 啊! 啊~ 啊! 啊. 啊啊啊啊啊啊啊...")
main_person_man = "张⽆忌"
main_person_woman = "赵敏"
low_person_man_one = "成昆"
low_person_man_two = "周芷若"
def fight_on_light_top(): print("光明顶⼤战", main_person_man, "破坏了", low_person_man_one, "的⼤阴谋")
def fight_in_shaolin():
print("少林寺⼤战", main_person_man, "破坏了", low_person_man_two, "的⼤阴谋")
接下来, ⾦庸上场.
import yitian
print(yitian.main_person_man) # 使⽤模块中定义好的名字
print(yitian.low_person_man_one)
yitian.fight_in_shaolin() # 调⽤模块中的函数
yitian.fight_on_light_top() 此时我们在⾦庸模块中引入了yitian模块.
在Python中模块是不能够重复导入的. 当重复导入模块时. 系统会根据sys.modules来判 断该模块是否已经导入了. 如果已经导入. 则不会重复导入
import sys 
print(sys.modules.keys()) # 查看导⼊的模块.
import yitian # 导⼊模块. 此时会默认执⾏该模块中的代码
import yitian # 该模块已经导⼊过了. 不会重复执⾏代码
import yitian
import yitian
import yitian
import yitian 导入模块的时候都做了些什么?
⾸先. 在导入模块的⼀瞬间. python解释器会先通过 sys.modules来判断该模块是否已经导入了该模块. 如果已经导入了则不再导入. 如果该模块
还未导入过. 则系统会做三件事.
1. 为导入的模块创⽴新的名称空间
2. 在新创建的名称空间中运⾏该模块中的代码
3. 创建模块的名字. 并使⽤该名称作为该模块在当前模块中引⽤的名字.

我们可以使⽤globals来查看模块的名称空间
print(globals())
打印结果:
{'__name__': '__main__', '__doc__': None, '__package__': None,
'__loader__': <_frozen_importlib_external.SourceFileLoader object at
0x10bbcf438>, '__spec__': None, '__annotations__': {}, '__builtins__':
<module 'builtins' (built-in)>, '__file__':
'/Users/sylar/PycharmProjects/oldboy/模块/模块/⾦庸.py', '__cached__': None,
'yitian': <module 'yitian' from '/Users/sylar/PycharmProjects/oldboy/模块/模块/yitian.py'>, 'sys': <module 'sys'="" (built-in)="">}

注意. 由于模块在导入的时候会创建其⾃⼰的名称空间. 所以. 我们在使⽤模块中的变量的时候⼀般是不会产⽣冲突的.

import yitian

main_person_man = "胡⼀菲"

def fight_in_shaolin():

print(main_person_man, "⼤战曾⼩贤")

print(yitian.main_person_man) # 张⽆忌

print(main_person_man) # 胡⼀菲

yitian.fight_in_shaolin() # 倚天屠⻰记中的 fight_in_shaolin() # ⾃⼰的 注意. 在模块中使⽤global. 我们之前说global表⽰把全局的内容引入到局部. 但是全局指的是py⽂件. 换句话说. global指向的是模块内部. 并不会改变外部模块的内容

模块 yitian 中:

print("⽚头曲. 啊! 啊~ 啊! 啊. 啊啊啊啊啊啊啊...")

main_person_man = "张⽆忌"

main_person_woman = "赵敏"

low_person_man_one = "成昆"

low_person_man_two = "周芷若"

def fight_on_light_top():

print("光明顶⼤战", main_person_man, "破坏了", low_person_man_one, "的⼤阴 谋")

def fight_in_shaolin():

  global low_person_man_two # 注意看, 此时的global是当前模块. 并不会影响 其他模块

low_person_man_two = "战五渣"

print("少林寺⼤战", main_person_man, "破坏了", low_person_man_two, "的⼤阴 谋")

调⽤⽅: import yitian low_person_man_two = "刘海柱"

yitian.fight_in_shaolin()

print(yitian.low_person_man_two) # 战五渣

print(low_person_man_two) # 刘海柱.并没有改变当前模块中的内容. 所以模块内部的 global只是⽤于模块内部

特别特别要注意. 如果我们在不同的模块中引入了同⼀个模块. 并且在某⼀个模块中改变了被引入模块中的全局变量. 则其他模块看到的值也跟着边. 原因是python的模块只会引入⼀次. ⼤家共享同⼀个名称空间

⾦庸: import yitian yitian

.main_person_man = "灭绝师太" ⾦庸⼆号:

import yitian import ⾦庸

print(yitian.main_person_man) # 灭绝师太.

上述问题出现的原因: 1. ⼤家共享同⼀个模块的名称空间.

2. 在⾦庸⾥改变了主⻆的名字 如何解决呢?

⾸先. 我们不能去改python. 因为python的规则不是我们定的. 只能想办法不要改变主 ⻆的名字. 但是. 在⾦庸⾥我就有这样的需求. 那此时就出现了. 在⾦庸被执⾏的时候要执⾏ 的代码. 在⾦庸被别⼈导入的时候我们不想执⾏这些代码. 此时, 我们就要利⽤⼀下__name__ 这个内置变量了. 在Python中. 每个模块都有⾃⼰的__name__ 但是这个__name__的值是不 定的. 当我们把⼀个模块作为程序运⾏的入⼝时. 此时该模块的__name__是"__main__" , ⽽如果我们把模块导入时. 此时模块内部的__name__就是该模块⾃⾝的名字

⾦庸: print(__name__) # 此时如果运⾏该⽂件. 则__name__是__main__

⾦庸⼆号: import ⾦庸 #此时打印的结果是"⾦庸"


posted on 2018-10-11 23:17  向往未来666  阅读(217)  评论(0编辑  收藏  举报