常用模块

一、re正则模块

1.正则符号

在线测试工具 http://tool.chinaz.com/regex/


img

贪婪匹配:
    默认都是贪婪匹配。贪婪匹配都是取大,比如:   *表示更多次、+表示多次、?表示一次,当然这只是默认的,当默认贪婪匹配不到,就会*表示零次、+表示一次、?表示零次

取消贪婪匹配:
	量词后面加问号(?)。 eg: 待匹配:李杰和李莲英和李二棍子    正则表达式:李.+?  结果:李杰   李莲  李二    ,因为+后面跟了?,所以+表示一次
        
    res3 = re.findall('李.?','李杰和李莲英和李二棍子')
	print(res3)
    # 结果:['李杰', '李莲', '李二']
    
转义符:

\   :   取消转义

  eg:  \\n 表示\n

2.正则方法

1.findall(全文查找返回):

1.找出字符串中符合正则的内容
    2.返回列表,列表中是正则表达匹配的内容
res = re.findall('a','asd jeff ball')
res1 = re.findall('[a-z]+','asd jeff ball')
print(res1)

结果:

2.search(从上至下查找):

1.返回一个对象,必须调用group才能看到结果
2.根据正则查找一次,只要查到结果就不会往后查找
3.当查找结果不存在(返回的None),再调用group直接报错,因为none没有group方法

res2 = re.search('a','asd jeff ball')
if res2:
    print(res2.group())
 # 结果 : a

3.match(匹配开头):

1.match匹配字符串开头
2.没有同样返回None
3.同样调用group报错

res3 = re.match('a','asd jeff ball')
if res3:
    print(res3.group())
    # 结果: a

res3 = re.match('a','sd jeff ball')
print(res3.group())
# 结果:报错,返回值为None,没有grop()这个方法

结果: 报错

4.split(切割):

ret = re.split('[ab]', 'abcd') # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
print(ret) # ['', '', 'cd']

str = "abcd,ssdhu,123"
print (str.split( )  )    # 以空格为分隔符,包含 \n
print (str.split(' ,', 1 ) )# 以逗号为分隔符,分隔成两个
# 结果:	['abcd,ssdhu,123']
		['abcd,ssdhu,123']

5.sub(替换)

ret = re.sub('999', 'H', 'jeff age max 999 8884', 2)# 将数字替换成'H',参数1表示只替换1个

print(ret)  
# 结果: jeff age max H 8884

6.subn(替换,返回元组)

ret = re.subn('4', '换', 'eva3egon4yuan4')  # 将数字替换成'H',返回元组(替换的结果,替换了多少次)
print(ret)
# 结果:
('eva3egon换yuan换', 2)   2:替换了两次

7.compile(正则封装为对象)

obj = re.compile('\d{3}')  #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串
print(ret.group())  #结果 : 123

8.finditer(迭代)

ret = re.finditer('\d', 'ds3sy4784a')   #finditer返回一个存放匹配结果的迭代器
print(ret)  # <callable_iterator object at 0x10195f940>
print(next(ret).group())  #查看第一个结果
print(next(ret).group())  #查看第二个结果
print([i.group() for i in ret])  #查看剩余的左右结果

9.分组

res = re.search('^[1-9]\d{14}(\d{2}[0-9x])?$',110105199812067023
print(res)

print(res.group(1))  # 获取正则表达式括号阔起来分组的内容
print(res.group(2))  # search与match均支持获取分组内容的操作  跟正则无关是python机制

10.起别名:

re.search('^[1-9]?P<passwd>(\d{14})(\d{2}[0-9x])?$',110105199812067023)
print(res.group(passwd))

3.正则应用场景

- 爬虫: re, BeautifulSoup4, Xpath, selector
- 数据分析过滤数据: re, pandas, numpy...
- 用户名与密码、手机认证:检测输入内容的合法性

4.正则练习

import re

ret = re.findall('a', 'eva egon yuan')  # 返回所有满足匹配条件的结果,放在列表里
print(ret) #结果 : ['a', 'a']

ret = re.search('a', 'eva egon yuan').group()
print(ret) #结果 : 'a'
# 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
# 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。

ret = re.match('a', 'abc').group()  # 同search,不过尽在字符串开始处进行匹配
print(ret)
#结果 : 'a'

ret = re.split('[ab]', 'abcd')  # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
print(ret)  # ['', '', 'cd']

ret = re.sub('\d', 'H', 'eva3egon4yuan4', 1)#将数字替换成'H',参数1表示只替换1个
print(ret) #evaHegon4yuan4

ret = re.subn('\d', 'H', 'eva3egon4yuan4')#将数字替换成'H',返回元组(替换的结果,替换了多少次)
print(ret)

obj = re.compile('\d{3}')  #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串
print(ret.group())  #结果 : 123

import re
ret = re.finditer('\d', 'ds3sy4784a')   #finditer返回一个存放匹配结果的迭代器
print(ret)  # <callable_iterator object at 0x10195f940>
print(next(ret).group())  #查看第一个结果
print(next(ret).group())  #查看第二个结果
print([i.group() for i in ret])  #查看剩余的左右结果

1.findall 的优先级查询

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']

2.split 的优先级查询

ret=re.split("\d+","eva3egon4yuan")
print(ret) #结果 : ['eva', 'egon', 'yuan']

ret=re.split("(\d+)","eva3egon4yuan")
print(ret) #结果 : ['eva', '3', 'egon', '4', 'yuan']

#在匹配部分加上()之后所切出的结果是不同的,
#没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项,
#这个在某些需要保留匹配部分的使用过程是非常重要的。

1.匹配标签

import re


ret = re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")
#还可以在分组中利用?<name>的形式给分组起名字
#获取的匹配结果可以直接用group('名字')拿到对应的值
print(ret.group('tag_name'))  #结果 :h1
print(ret.group())  #结果 :<h1>hello</h1>

ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>")
#如果不给组起名字,也可以用\序号来找到对应的组,表示要找的内容和前面的组内容一致
#获取的匹配结果可以直接用group(序号)拿到对应的值
print(ret.group(1))
print(ret.group())  #结果 :<h1>hello</h1>

2.匹配整数

import re

ret=re.findall(r"\d+","1-2*(60+(-40.35/5)-(-4*3))")
print(ret) #['1', '2', '60', '40', '35', '5', '4', '3']
ret=re.findall(r"-?\d+\.\d*|(-?\d+)","1-2*(60+(-40.35/5)-(-4*3))")
print(ret) #['1', '-2', '60', '', '5', '-4', '3']
ret.remove("")
print(ret) #['1', '-2', '60', '5', '-4', '3']

3.数字匹配

1、 匹配一段文本中的每行的邮箱
      http://blog.csdn.net/make164492212/article/details/51656638

2、 匹配一段文本中的每行的时间字符串,比如:‘1990-07-12’;

   分别取出1年的12个月(^(0?[1-9]|1[0-2])$)、
   一个月的31天:^((0?[1-9])|((1|2)[0-9])|30|31)$

3、 匹配qq号。(腾讯QQ号从10000开始)  [1,9][0,9]{4,}

4、 匹配一个浮点数。       ^(-?\d+)(\.\d+)?$   或者  -?\d+\.?\d*

5、 匹配汉字。             ^[\u4e00-\u9fa5]{0,}$ 

6、 匹配出所有整数

4.爬虫练习

import requests

import re
import json

def getPage(url):

    response=requests.get(url)
    return response.text

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=json.dumps(obj,ensure_ascii=False)
        f.write(data+"\n")

if __name__ == '__main__':
    count=0
    for i in range(10):
        main(count)
        count+=25

简化版:

import re
import json
from urllib.request import urlopen

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

flags

flags有很多可选值:

re.I(IGNORECASE)忽略大小写,括号内是完整的写法
re.M(MULTILINE)多行模式,改变^和$的行为
re.S(DOTALL)点可以匹配任意字符,包括换行符
re.L(LOCALE)做本地化识别的匹配,表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境,不推荐使用
re.U(UNICODE) 使用\w \W \s \S \d \D使用取决于unicode定义的字符属性。在python3中默认使用该flag
re.X(VERBOSE)冗长模式,该模式下pattern字符串可以是多行的,忽略空白字符,并可以添加注释

二、collertion模块

1.collertion模块基本方法:

1.namedtuple 具名元组(给元组取名)
2.deque 双端队列(左中右添加值,左右取值)
3.OrderedDict 有序字典
4.Counter方法(计算计算字符串的每个字符的个数,并以字典返回)

1.namedtuple 具名元组

from collections import namedtuple
point = namedtuple('坐标', ['x', 'y', 'z'])
p = point(2, 5, 8)
print(p)
print(p.x)
print(p.y)
print(p.z)

结果:坐标(x=2, y=5, z=8)   2   5    8

from collections import namedtuple
card = namedtuple('扑克牌', 'color number')
A = card('♠', 'A')
print(A)
print(A.color)
print(A.number)
结果:扑克牌(color='♠', number='A')    ♠  A

2.queue.Queue队列 deque双端队列

import queue
q = queue.Queue()  # 生成队列对象
q.put('one')   # 传值
q.put('two')
q.put('three')

print(q.get())  # 朝着队列要值,如果取完了,程序原地等待(不结束)
print(q.get())
print(q.get())
print(q.get())

2.deque双端队列

四个方法:
1.append 尾部追加
2.appendleft 左边追加
3.pop 末尾取值
4.popleft 左边取值
5.insert(索引,'值') 根据索引插值

from collections import deque
q = deque(['a', 'b', 'c'])
q.append('尾')
q.appendleft('左')
q.insert(1, '插')   # 在索引1位置插入
print(q.pop())  # 结果: 尾
print(q.popleft())  # 结果: 左
print(q.popleft())  # 结果: 插

3.有序字典

from collections import OrderedDict
k = OrderedDict()
k['x'] = 1  # 给固定的键传值
k['y'] = 2
k['z'] = 3

表现:

print(k)
for i in k:
    print(i)

4.Counter计算字符次数方法与普通for循环方法

计算字符串中每隔字符出现的次数:

k = 'abcaabca'
d = {}
# 字典的key是固定的,先建一个值为0的字典
for i in k:
    d[i] = 0
# 每个字符和字典的key作比较,有就加1
for q in k:
    for n in d:
        if n == q:
            d[q] += 1
print(d)
2.Counter方法
from collections import Counter
k = 'abcaabca'
res = Counter(k)
print(res)

四、time与datetime模块

1.time与datetime模块:

import time
print(time.time())  # 距离1970.01.01的秒数
print(time.strftime('%Y-%m-%d %H:%m:%s'))  # 拼接时间格式
print(time.localtime())
time.sleep(3)  # 程序暂停3秒

Django中改变内置时区:
在setting.py中:改为
	TIME_ZONE = 'Asia/Shanghai'
    USE_TZ = False

2.时间:

import datetime
print(datetime.date.today())  # 年月日
print(datetime.datetime.today())  # 年月日 时分秒
res = datetime.date.today()
res1 = datetime.datetime.today()
print(res.year)  # 年
print(res.month)  # 月
print(res.day)   # 日
print(res.weekday())  # 第几个星期(从0开始)
print(res.isoweekday())  # 第几个星期(从1开始)
datetime.datetime.fromtimestamp(时间戳)   # 时间戳转换为datime格式

3.时间计算

# 时间计算
import datetime
a = datetime.datetime(2019, 12, 15, 5, 5, 5)
b = datetime.datetime.today()
print(a-b)  #  现在时间-指定时间
UTC时间:
import datetime
a = datetime.datetime.today()
b = datetime.datetime.now()
c = datetime.datetime.utcnow()   #一区时间,上海东八区
print(a)
print(b)
print(c)

五、arrow加强版datetime模块

In [1]: import arrow 
 
# 基准的时区,第一种写法 
In [2]: now = arrow.now('local') 
In [3]: now 
Out[3]: <Arrow [2018-11-06T12:23:53.594706+08:00]> 
 
# 切换时区的写法 
In [4]: now2 = arrow.now().to('local') 
In [5]: now2 
Out[5]: <Arrow [2018-11-06T12:24:18.191082+08:00]> 
 
# 格式化输出日期 
In [6]: now.format('YYYY-MM-DD') 
Out[6]: '2018-11-06' 
 
# 格式化输出日期及时分秒 
In [7]: now.format('YYYY-MM-DD HH:mm:ss') 
Out[7]: '2018-11-06 12:23:53' 
 
# 按天偏移(-1为昨天, 0为当天, 1为明天,以此类推) 
In [8]: now.shift(days=-1).format('YYYY-MM-DD') 
Out[8]: '2018-11-05' 
 
# 按月偏移(-1为上个月,0为本月, 1为下个月,以此类推) 
In [9]: now.shift(months=-1).format("YYYYMMDD") 
Out[9]: '20181006' 
 
# 返回当天是本周中的哪一天(下面2的意思即为周二) 
In [10]: now.format('d') 
Out[10]: '2' 
 
# 返回当天是本月中的哪一天 
In [11]: now.format('D') 
Out[11]: '6' 
 
# 获取当前时间戳 
In [12]: now.timestamp 
Out[12]: 1541478233 
 
# 将时间戳转为可读性的时间 
In [13]: stamp = 1533890211 
In [14]: arrow.get(stamp) 
Out[14]: <Arrow [2018-08-10T08:36:51+00:00]> 
 
# 将时间转为人性化的,比如:'an hour ago' 
In [15]: now.humanize() 
Out[15]: '16 minutes ago' 
 
# 当天的开始时间, 即:当日00:00:00 
In [16]: now.floor('day') 
Out[16]: <Arrow [2018-11-06T00:00:00+08:00]> 
 
# 获取当月最初的时间,即:当月1日00:00:00 
In [17]: now.floor('month') 
Out[17]: <Arrow [2018-11-01T00:00:00+08:00]> 
 
# 当天的结束时间, 即:当日23:59:59 
In [18]: now.ceil('day') 
Out[18]: <Arrow [2018-11-06T23:59:59.999999+08:00]> 
 
# 获取当月最后的时间,即:当月最后1日23:59:59 
In [19]: now.ceil('month') 
Out[19]: <Arrow [2018-11-30T23:59:59.999999+08:00]> 
 
# 从类似日期的字符串转为日期格式的数据 
In [20]: arrow.get('20181010', 'YYYYMMDD').format("YYYY-MM-DD") 
Out[20]: '2018-10-10' 
 
# 生成日期连续的日期区间 
In [21]: start = arrow.get('2018-09-01','YYYY-MM-DD') 
In [22]: end = arrow.get('2018-09-10','YYYY-MM-DD') 
In [23]: [dt for dt in arrow.Arrow.range('day',start,end)] 
Out[23]: [<Arrow [2018-09-01T00:00:00+00:00]>, <Arrow [2018-09-02T00:00:00+00:00]>, <Arrow [2018-09-03T00:00:00+00:00]>, <Arrow [2018-09-04T00:00:00+00:00]>, <Arrow [2018-09-05T00:00:00+00:00]>, <Arrow [2018-09-06T00:00:00+00:00]>, <Arrow [2018-09-07T00:00:00+00:00]>, <Arrow [2018-09-08T00:00:00+00:00]>, <Arrow [2018-09-09T00:00:00+00:00]>, <Arrow [2018-09-10T00:00:00+00:00]>] 
 
# 单位时间跨度的起止时间 
In [25]: now.span('hour') 
Out[25]: (<Arrow [2018-11-06T12:00:00+08:00]>, <Arrow [2018-11-06T12:59:59.999999+08:00]>) 
In [26]: now.span('month') 
Out[26]: (<Arrow [2018-11-01T00:00:00+08:00]>, <Arrow [2018-11-30T23:59:59.999999+08:00]>) 
In [27]: now.span('week') 
Out[27]: (<Arrow [2018-11-05T00:00:00+08:00]>, <Arrow [2018-11-11T23:59:59.999999+08:00]>) 
In [28]: now.span('day') 
Out[28]: (<Arrow [2018-11-06T00:00:00+08:00]>, <Arrow [2018-11-06T23:59:59.999999+08:00]>) 
 
# replace的使用方法, 结果前后对比 
In [29]: now.format('YYYYMMDD HH:mm:ss') 
Out[29]: '20181106 12:23:53' 
In [30]: now.replace(hour=0, minute=30,second=0).format('YYYYMMDD HH:mm:ss') 
Out[30]: '20181106 00:30:00'

六、random随机模块

random.seed(a=None, version=2)  # 初始化伪随机数生成器,若种子a相同,则可以使生成的随机数相同。如果未提供a或者a=None,则使用系统时间为种子。
random.random()  # 返回一个介于左闭右开[0.0, 1.0)区间的浮点数。
random.randint(a, b)  # 返回range[a,b]之间的一个整数。
random.uniform(a, b)  # 返回一个介于a和b之间(含a,b)的浮点数。如果a>b,则是b到a之间的浮点数。
random.randrange(start, stop[, step])  # 返回range[start,stop)之间的一个整数,可加步长step,跟range(0,10,2)类似。
random.choice(seq)  # 从非空序列seq中随机选取一个元素。如果seq为空则弹出 IndexError异常。
random.choices(population, weights=None, *, cum_weights=None, k=1)  # 3.6版本新增!从population集群中随机抽取K个元素(可重复)。weights是相对权重列表,cum_weights是累计权重,两个参数不能同时存在。
random.sample(population, k)  # 从population样本或集合中随机抽取K个元素(不重复)形成新的序列。常用于不重复的随机抽样、打乱序列。
random.shuffle(x[, random])  # 随机打乱序列x内元素的排列顺序。只能针对可变的序列,对于不可变序列,请使用sample()方法。

random.triangular(low, high, mode)  # 返回一个N∈[low, high]的三角形分布的随机数。参数mode指明众数出现位置。
random.betavariate(alpha, beta)  # β分布。返回的结果在0~1之间。
random.gammavariate(alpha, beta)  # 伽玛分布。
random.expovariate(lambd)  # 指数分布。
random.gauss(mu, sigma)  # 高斯分布。
random.normalvariate(mu, sigma)  # 正态分布。
random.lognormvariate(mu, sigma)  # 对数正态分布。
random.vonmisesvariate(mu, kappa)  # 卡帕分布。
random.paretovariate(alpha)  # 帕累托分布。
random.weibullvariate(alpha, beta)  # 威布尔分布。
random.getstate()  # 返回一个当前生成器的内部状态的对象。
random.setstate(state)  # 传入一个先前利用getstate方法获得的状态对象,使得生成器恢复到这个状态。

# 随机模块
import random

print(random.randint(0, 9))  # 随机取一个0-9的数字,包含头尾
print(random.random)  # 取0-1之间的小数
print(random.choice([1, 2, 3, 4]))  # 随机从列表中取一个值
print(random.uniform(1,10))#1-10小数,如1.927109612082716 
random.randrange(1,10,2) # 大于等于1且小于10之间的奇数

打乱顺序shuffle:

res = [1, 2, 3, 4, 5]
random.shuffle(res)  # 打乱列表的顺序
print(res)
# 生成随机验证码
a = str(random.randint(0, 9))   # 转成字符串型,才可以相加拼接
b = chr(random.randint(65, 90))  # 大写字母 65-90
c = chr(random.randint(97, 122))  # 小写字母  97-122
# print(a, b, c)
k = ''
for i in range(5):
    m = random.choice([a, b, c])
    k += m   # 让字符串相加,而不是数字
print(k)
m = random.randint(0, 9)
print(type(a))
print(type(m))

随机验证码:

import random

def v_code():

    code = ''
    for i in range(5):

        num=random.randint(0,9)
        alf=chr(random.randint(65,90))
        add=random.choice([num,alf])
        code="".join([code,str(add)])

    return code

print(v_code())

七、sys模块和subprocess子进程模块

1.sys模块跟python解释器打交道的

2.sys中的一些方法

import sys
sys.path.append() # 将某个路径添加到环境变量中
print(sys.platform) # 查看当前操作系统
print(sys.version) # python解释器的版本
print(sys.argv) # 命令启动文件 可以做身份验证

3.subprocess 子进程模块

subprocess 子进程模块
"""
sub :子
process:进程
"""

例子1:
输出cmd命令并返回结果:
while True:
    cmd = input('cmd>>>:').strip()
    import subprocess
    obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    print('正确命令返回结果stdout',obj.stdout.read().decode('gbk'))
    print('错误命令返回的提示信息stdout',obj.stdout.read().decode('gbk'))

八、json和pickle序列化模块

0.demjson处理不标准的json

pip install demjson
demjson.decode(str)  # 字符串转json
demjson.encode(str)  # json转字符串

1.json和pickle的区别特点

json:可以和其他语言玩

pickle:只能和自己(python)玩

2.json 中的一些方法

dumps(转): 编码,纯粹的数据使用,将其他数据类型转成json格式的字符串
loads(解): 解码,纯粹的数据使用,将json格式字符串转换成其他数据类型
dump(转文件): 编码,写文件中的数据,将其他数据类型转成json格式的字符串
load(解文件): 解码,读文件中的数据,将json格式字符串转换成其他数据类型

ensure_ascii=False False表示字典中的汉字不转,Turn表示转中文,默认为Trun

优点: 1.所有语言都支持json格式
缺点: 2.支持的数据类型少
pickle()
优点: 1.python所有数据类型都支持
缺点: 2.只支持python

3.序列化

序列化:
序列:字符串
序列化:其他数据类型转成字符串的过程
  序列化:其他数据类型转成字符串的过程
  反序列化:字符串转成其他数据类型

注意:
  写入文件的数据必须是字符串(二进制)
  基于网络传输的数据必须是二进制

例子1:
将字典转换成字符串:k = {'name': 'jeff'}
res = json.dumps(k)
print(res) # 结果:{"name": "jeff"}
print(res, type(res)) # 结果:{"name": "jeff"} <class 'str'>

将上面的字符串转为字典:

res1 = json.loads(res)
print(res1, type(res1))  结果:{'name': 'jeff'} <class 'dict'>

例子2:对文件的中的内容转换:

转换类型,并写入文件:

d = {"name":"jeff"}
with open(r'userinfo','w',encoding='utf-8') as f:
    json.dump(d, f)  # 转字符,并自动写入文件

读取内容,并解为python类型:

with open(r'userinfo', 'r', encoding='utf-8') as f:
    res = json.load(f)  # 解字符,并读取
    print(res, type(res))

例子3:
ensure_ascii=False  表示字典中的汉字不转
中文不转码:
d = {'name': '辜老板'}
print(json.dumps(d, ensure_ascii=False))   # ensure_ascii=False识别中文不转码
#结果:{"name": "辜老板"}

中文转码:

d = {'name': '辜老板'}
print(json.dumps(d, ensure_ascii=True))   # ensure_ascii=False识别中文不转码
# 结果:{"name": "\u8f9c\u8001\u677f"}    中文转码了

九、hashlib加密模块

hashlib加密模块:不可逆,但是可以撞库

1.hashlib常用方法

md.update('数据'): 没有提示,记住单词
md.hexdigest() :获取密文,记住单词

hashlib加盐:用手动传入假数据(动态)和真数据混合在一起加密

MD5:常用加密算法

2.hashlib应用场景

1.密码的密文储存
2.校验文件内容是否一致

1.加密:

md = hashlib.md5()   #  加密,不可逆
md.update('hello'.encode('utf-8'))   # 往对象里传数据加密  ,update只能接受bytes类型
md.update(b'hello')
print(md.hexdigest())

结果:23b431acfeb41e15d466d75de822307c

2.加盐加密:自己添加的东西和客户的真密码一起加密,自己添加的东西可以是动态的

2.加盐  :自己添加的东西和客户的真密码一起加密,自己添加的东西可以是动态的
md = hashlib.md5()
md.update(b'yan.com')
md.update(b'hello')   # 加密
print(md.hexdigest())  # 获取密文

例子1:给客户输入的密码加盐加密

import hashlib
# 加盐
def get_md5(date):
    md = hashlib.md5()
    md.update('加盐'.encode('utf-8'))
    md.update(date.encode('utf-8'))
    return md.hexdigest()
password = input('password>>>:')
res = get_md5(password)
print(res)

十、murmurhash3非加密哈希

加密哈希,如MD5,SHA256等,
非加密哈希,如MurMurHash,CRC32,DJB等

​ 能够满足这样的哈希算法有很多,这里推荐 Google 出品的 MurmurHash 算法,MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。与其它流行的哈希函数相比,对于规律性较强的 key,MurmurHash 的随机分布特征表现更良好。非加密意味着着相比 MD5,SHA 这些函数它的性能肯定更高(实际上性能是 MD5 等加密算法的十倍以上),也正是由于它的这些优点,所以虽然它出现于 2008,但目前已经广泛应用到 Redis、MemCache、Cassandra、HBase、Lucene 等众多著名的软件中。

pip install murmurhash3

import mmh3
a=mmh3.hash('hello word',seed=0x1234ABCD)
b=mmh3.hash64('hello word',seed=0x1234ABCD)
c=mmh3.hash128('hello word')
d=mmh3.hash_bytes('hello word')
print(a) # 1380922724
print(b) # (4946771540764450955, -2295991620757091750)
print(c) # 287071001001438644664654856278143820788
print(d) # b'\xf4c\x92\x91}+\xc9\x90\xd4\xd64g\x1b\xdd\xf7\xd7'

十一、loggin日志模块

标准三流

""" 标准三流
import sys
sys.stderr.write('aaaaaaa/n')  # 错误流    结果红色(日志)
sys.stdout.write('bbbbbbb/n')  # 正常流    结果黑色(正常流)
res = sys.stdin.readline()     # 标准输入流 等待输入,然后打印。黑色
print(res)
"""

一、日志级别

CRITICAL = 50 #FATAL = CRITICAL
ERROR = 40
WARNING = 30 #WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0 #不设置

二、默认级别为warning,默认打印到终端

import logging

logging.debug('调试debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('错误error')
logging.critical('严重critical')

'''
WARNING:root:警告warn
ERROR:root:错误error
CRITICAL:root:严重critical
'''

三、为logging模块指定全局配置,针对所有logger有效,控制打印到文件中

可在logging.basicConfig()函数中通过具体参数来更改logging模块默认行为,可用参数有
filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format:指定handler使用的日志显示格式。 
datefmt:指定日期时间格式。 
level:设置rootlogger(后边会讲解具体概念)的日志级别 
stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。



#格式
%(name)s:Logger的名字,并非用户名,详细查看

%(levelno)s:数字形式的日志级别

%(levelname)s:文本形式的日志级别

%(pathname)s:调用日志输出函数的模块的完整路径名,可能没有

%(filename)s:调用日志输出函数的模块的文件名

%(module)s:调用日志输出函数的模块名

%(funcName)s:调用日志输出函数的函数名

%(lineno)d:调用日志输出函数的语句所在的代码行

%(created)f:当前时间,用UNIX标准的表示时间的浮 点数表示

%(relativeCreated)d:输出日志信息时的,自Logger创建以 来的毫秒数

%(asctime)s:字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒

%(thread)d:线程ID。可能没有

%(threadName)s:线程名。可能没有

%(process)d:进程ID。可能没有

%(message)s:用户输出的消息

介绍

#======介绍
可在logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有
filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format:指定handler使用的日志显示格式。
datefmt:指定日期时间格式。
level:设置rootlogger(后边会讲解具体概念)的日志级别
stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。


format参数中可能用到的格式化串:
%(name)s Logger的名字
%(levelno)s 数字形式的日志级别
%(levelname)s 文本形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(filename)s 调用日志输出函数的模块的文件名
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process)d 进程ID。可能没有
%(message)s用户输出的消息

使用

#========使用
import logging
logging.basicConfig(filename='access.log',
                    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S %p',
                    level=10)

logging.debug('调试debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('错误error')
logging.critical('严重critical')





#========结果
access.log内容:
2017-07-28 20:32:17 PM - root - DEBUG -test:  调试debug
2017-07-28 20:32:17 PM - root - INFO -test:  消息info
2017-07-28 20:32:17 PM - root - WARNING -test:  警告warn
2017-07-28 20:32:17 PM - root - ERROR -test:  错误error
2017-07-28 20:32:17 PM - root - CRITICAL -test:  严重critical

part2: 可以为loggin
    g模块指定模块级的配置,即所有logger的配置

十二、base64

data = data.encode('utf8')  # 必须转成二进制
    
# encodebytes,b64encode都可以
encodeStrTest = base64.encodebytes(data) # 对字符串编码 
encodeStrTest = base64.b64encode(data)

# 对字符串解码
decodeStrTest = base64.decodebytes(encodeStrTest).decode('utf-8')

# 编码
def base64_encode(data):
    data = data.encode('utf8')  # 必须转成二进制
    # 对字符串编码
    encodeStrTest = base64.encodebytes(data)  # encodebytes,b64encode都可以
    return encodeStrTest


# 解码
def base64_decode(data):
    # 对字符串解码
    decodeStrTest = base64.decodebytes(data).decode('utf-8')  # 解码
    return decodeStrTest

十三、pymysql模块

这个模块可以操作MySQL的模块

用的时候需要下载一下这个模块

例子:

import pymysql

conn = pymysql.connect(
    host = '127.0.0.1',
    port = 3306,
    user = 'root',
    password = '123',
    database = 'jeff',
    charset = 'utf8'
)

cursor = conn.cursor(pymysql.cursors.DictCursor)  # 产生游标对象,以字典的形式返回
sql = 'select * from teacher'
cursor.execute(sql)  # 执行传入的sql语句
# print(cursor.fetchone())  # 只获取一条数据
# print(cursor.fetchone())  # 只获取一条数据
# print(cursor.fetchone())  # 只获取一条数据
# print(cursor.fetchone())  # 只获取一条数据
# cursor.scroll(2,'absolute')  # 控制光标移动   absolute相对于其实位置 往后移动几位
# cursor.scroll(1,'relative')  # relative相对于当前位置 往后移动几位
print(cursor.fetchall())  # 获取所有的数据  返回的结果是一个列表

十四、uuid

概述:

    UUID是128位的全局唯一标识符,通常由32字节的字符串表示。
    它可以保证时间和空间的唯一性,也称为GUID,全称为:
            UUID —— Universally Unique IDentifier      Python 中叫 UUID
            GUID —— Globally Unique IDentifier          C#  中叫 GUID

    它通过MAC地址、时间戳、命名空间、随机数、伪随机数来保证生成ID的唯一性。
    UUID主要有五个算法,也就是五种方法来实现:
使用方面:

    首先,Python中没有基于DCE的,所以uuid2可以忽略;
    其次,uuid4存在概率性重复,由无映射性,最好不用;
    再次,若在Global的分布式计算环境下,最好用uuid1;
    最后,若有名字的唯一性要求,最好用uuid3或uuid5。

  1. uuid.uuid1([node[, clock_seq]]) -- 基于时间戳

由 MAC 地址(主机物理地址)、当前时间戳、随机数生成。可以保证全球范围内的唯一性,
但 MAC 的使用同时带来安全性问题,局域网中可以使用 IP 来代替MAC。

该函数有两个参数, 如果 node 参数未指定, 系统将会自动调用 getnode() 函数来获取主机的硬件地址. 如果 clock_seq 参数未指定系统会使用一个随机产生的14位序列号来代替.

注意: uuid1() 返回的不是普通的字符串,而是一个 uuid 对象,其内含有丰富的成员函数和变量。

  1. uuid.uuid2() -- 基于分布式计算环境DCE(Python中没有这个函数)

算法与uuid1相同,不同的是把时间戳的前 4 位置换为 POSIX 的 UID。
实际中很少用到该方法。

  1. uuid.uuid3(namespace, name) -- 基于名字的MD5散列值

通过计算名字和命名空间的MD5散列值得到,保证了同一命名空间中不同名字的唯一性,
和不同命名空间的唯一性,但同一命名空间的同一名字生成相同的uuid。

  1. uuid.uuid4() -- 基于随机数

由伪随机数得到,有一定的重复概率,该概率可以计算出来。

产生一个唯一的随机字符串
import uuid
a = str(uuid.uuid4())
print(len(a))
print(a)

  1. uuid.uuid5() -- 基于名字的SHA-1散列值

算法与uuid3相同,不同的是使用 Secure Hash Algorithm 1 算法

十五.OS模块

os.makedirs('dirname1/dirname2')    可生成多层递归目录
os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname')    生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname')    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname')    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove()  删除一个文件
os.rename("oldname","newname")  重命名文件/目录
os.stat('path/filename')  获取文件/目录信息

os.system("bash command")  运行shell命令,直接显示
os.popen("bash command).read()  运行shell命令,获取执行结果
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd

os.path
os.path.abspath(path) 返回path规范化的绝对路径
os.path.split(path) 将path分割成目录和文件名二元组返回 
os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 
os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path)  如果path是绝对路径,返回True
os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path)  返回path所指向的文件或者目录的最后访问时间
os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间
os.path.getsize(path) 返回path的大小

注意:os.stat('path/filename')  获取文件/目录信息 的结构说明


复制代码
stat 结构:

st_mode: inode 保护模式
st_ino: inode 节点号。
st_dev: inode 驻留的设备。
st_nlink: inode 的链接数。
st_uid: 所有者的用户ID。
st_gid: 所有者的组ID。
st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。
st_atime: 上次访问的时间。
st_mtime: 最后一次修改的时间。
st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间(详细信息参见平台的文档)。
复制代码

os.sep    输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep    输出当前平台使用的行终止符,win下为"\r\n",Linux下为"\n"
os.pathsep    输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'

十六、math模块

ceil:取大于等于x的最小的整数值,如果x是一个整数,则返回x

copysign:把y的正负号加到x前面,可以使用0

cos:求x的余弦,x必须是弧度

degrees:把x从弧度转换成角度

e:表示一个常量

exp:返回math.e,也就是2.71828的x次方

expm1:返回math.e的x(其值为2.71828)次方的值减1

fabs:返回x的绝对值

factorial:取x的阶乘的值

floor:取小于等于x的最大的整数值,如果x是一个整数,则返回自身

fmod:得到x/y的余数,其值是一个浮点数

frexp:返回一个元组(m,e),其计算方式为:x分别除0.5和1,得到一个值的范围

fsum:对迭代器里的每个元素进行求和操作

gcd:返回x和y的最大公约数

hypot:如果x是不是无穷大的数字,则返回True,否则返回False

isfinite:如果x是正无穷大或负无穷大,则返回True,否则返回False

isinf:如果x是正无穷大或负无穷大,则返回True,否则返回False

isnan:如果x不是数字True,否则返回False

ldexp:返回x*(2**i)的值

log:返回x的自然对数,默认以e为基数,base参数给定时,将x的对数返回给定的base,计算式为:log(x)/log(base)

log10:返回x的以10为底的对数

log1p:返回x+1的自然对数(基数为e)的值

log2:返回x的基2对数

modf:返回由x的小数部分和整数部分组成的元组

pi:数字常量,圆周率

pow:返回x的y次方,即x**y

radians:把角度x转换成弧度

sin:求x(x为弧度)的正弦值

sqrt:求x的平方根

tan:返回x(x为弧度)的正切值

trunc:返回x的整数部分

十七、importlib 字符串路径

import importlib
moudle_path='字符串路径'
importlib.import_module(moudle_path)

十八、traceback详细错误信息

import traceback

res['data'] = '错误信息:%s'%(traceback.format_exc())


'''
traceback.format_exc() # 获取详细的错误信息,定位到哪一行代码
'''

十九、translate翻译器

from translate import Translator


def covert(char):
    """
    翻译器
    from_lang:输入语言
    to_lang:输出语言
    chinese
    english
    Japanese 日本
    Korean 韩语
    German 德语
    Spanish 西班牙语
    """
    translator = Translator(from_lang="chinese", to_lang="english")
    return translator.translate(char)


if __name__ == '__main__':
    print(covert("你好"))
posted @ 2019-08-13 10:33  Jeff的技术栈  阅读(319)  评论(0编辑  收藏  举报
回顶部