欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python day 8: re模块补充,导入模块,hashlib模块,字符串格式化,模块知识拾遗,requests模块初识

程序员文章站 2022-07-02 12:48:19
python day 8 2019/10/11 资料来自老男孩教育 [TOC] 1. re模块补充 2. import模块导入 import是导入模块的关键字。 模块分为三类:内置模块,标准模块,第三方模块。 模块的导入路径是sys.path中的各个元素,python解释器去sys.path的各个路 ......

目录

python day 8

2019/10/11

资料来自老男孩教育

1. re模块补充

import re

data = 'hello my name is lanxing and hello 30, i am very pleased to meet you guys.'
# 从头匹配:match(pattern, string, flags=0) flags:i(忽略大小写),m(多行),s(.能匹配所有包括换行符),x(忽略pattern的注释)
# 无分组的情况下
ret = re.match('h\w+', data)  # 匹配成功返回匹配对象,具有以下的group方法,不成功则返回none,不具有下列方法
print(ret.group())  # group方法返回匹配到的所有字符串
print(ret.groups())  # groups方法返回匹配结果中的分组结果,以元组形式将分组结果进行展示
print(ret.groupdict())  # groupdict方法返回匹配结果的分组中所有执行了key的组。
'''
hello
()
{}
'''
# 有分组的情况下:
ret2 = re.match('(?p<n1>h)(?p<name2>\w+)', data)  # ?p<n1>是给分组起了个名字叫n1,这个组的key就是n1,后面可以通过这个key来引用这个分组结果。
print(ret2.group())  # group方法返回匹配到的所有字符串,返回结果是一个字符串
print(ret2.groups())  # groups方法返回匹配结果中的分组结果,将每一个分组结果作为元组的元素进行返回。
print(ret2.groupdict())  # groupdict方法返回匹配结果的分组中所有执行了key的组。是一个字典
'''
hello
('h', 'ello')
{'n1': 'h', 'name2': 'ello'}
'''
# search(pattern,str,flags=0),搜索整个字符串,匹配出现的第一个pattern

ret3 = re.search('h(\w+).*(?p<num>\d)', data,flags=re.i)  # 不加原生字符串标志r,就需要再加一个python转义符\
print(ret3.group())  # group方法返回匹配到的所有字符串,返回结果是一个字符串
print(ret3.groups())  # groups方法返回匹配结果中的分组结果,将每一个分组结果作为元组的元素进行返回。
print(ret3.groupdict())  # groupdict方法返回匹配结果的分组中所有执行了key的组。是一个字典
'''
hello my name is lanxing and hello 30
('ello', '0')
{'num': '0'}
'''

#findall(pattern,str,flags=0),搜索整个字符串,匹配符合pattern的所有字符,并返回一个列表
#1,无分组的情况下,以列表返回所有符合pattern的匹配结果,且匹配结果是不可重叠的。
ret4 = re.findall('\d+\w\d+','a2b3c4d5')  # return a list of all non-overlapping matches in the string
print(ret4)
ret5 = re.findall('','a2b3c4d5')  # 匹配结果为空也会包含在列表中。
print(ret5)
#  ['', '', '', '', '', '', '', '', '']
# 2,只有一个分组的情况下,会将groups元组里面的元素单独拿出来,作为列表的元素进行返回。
n = re.search('h(?p<name1>\w+).*\d','abhw23, hel54')
print(n.group())  # hw23, hel54
print(n.groups())  # ('w23',)
n1 = re.findall('h(?p<name1>\w+).*\d','abhw23, hel54')
print(n1)  # ['w23']


#3,超过1个分组的情况下,优先返回分组的匹配结果,即将groups的结果放进列表中进行返回,给分组起别名在findall中是没用的。。
ret6 = re.findall('h(?p<name1>\w+).*(\d)','abhw23, hel54')
print(ret6)  #[('w23', '4')]
ret7 = re.findall('h(\w+(d)).*(\d)','abhwd23, hel54')  #每一个括号的内容都作为元组的元素,该元组再作为列表的元素返回。
print(ret7)  #[('wd', 'd', '4')]
# #搜索整个字符串,匹配符合pattern的字符串,并返回一个迭代器
ret8= re.finditer('h(\w+(?p<name1>d)).*(\d)','abhwd23, hel54')
print(ret8)
for i in ret8:
    print(i,i.group(),i.groups(),i.groupdict(),sep='\n')

# <callable_iterator object at 0x0000017bed3a8da0>
# <re.match object; span=(2, 14), match='hwd23, hel54'>
# hwd23, hel54
# ('wd', 'd', '4')
# {'name1': 'd'}
m1 = re.findall('(\w)(\w)(\w)(\w)','hello')  #以实际分组有多少个,列表中的嵌套元组才会有多少个元素。
print(m1)  #[('h', 'e', 'l', 'l')]
m2 = re.findall('(\w){4}','hello')  #如果分组实际显示的只有一个,则默认匹配最后一次符合要求的字符串
print(m2)  #['l']
m3 = re.findall('(\w)*','hello')  #因为贪婪匹配默认匹配多个,而*是代表可有可无,所以匹配到o时,*代表pattern是none,再匹配一次。返回空值。
print(m3)  # ['o', '']
m4 = re.findall('(\dasd)*','1asd2asdp3asd98132')  #轮到p的时候,*为0的情况出现了,意味着pattero为none。到98132时,*为0的情况也出现了,都返回空值。
print(m4)
m5 = re.findall('(\dasd)+','1asd2asdp3asd98132')  #如果是+就不会出现这种情况了。即有数量表示符*,+,{m,n}的情况默认匹配最后一次符合pattern的字符串。
print(m5)


#re.split(pattern, string, maxsplit=0, flags=0),首先是找到所有的匹配字符,再根据匹配字符进行分割并返回列表,如果有分组情况,则分组的结果也将在列表中。
# 1,无分组的情况下:
data = 'hello my name is lanxing and hello 30, i am very pleased to meet you guys.'
print( re.findall('m\w',data) )  #  ['my', 'me', 'me']
li1 = re.split('m\w',data,maxsplit=2)  #可以限定将findall中的多少个元素作为分割元素。
print(li1)  #  ['hello ', ' na', ' is lanxing and hello 30, i am very pleased to meet you guys.']

# 2,有分组的情况下:
print( re.findall('m(\w)',data) )
li2 = re.split('m(\w)',data,1)  # 会将分组内容提取出来,并作为元素返回在列表中
print(li2)

#sub(pattern, repl, string, count=0, flags=0),将匹配内容进行替换,count如果是0代表替换所有的匹配内容。
print(re.sub('\d','kk','1as23fe'))  #返回替换后的字符串
print(re.subn('\d','kk','1as23fe'))  #返回一个元组 ('kkaskkkkfe', 3),替换了3次

# 1 - 2 *((60-30+(-40.0/5)*(9-2*5/3 +7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))
# 首先匹配最里层的括号,算出其值,再匹配外面一层的括号
num = '1 - 2 *((60-30+(-40.0/5)*(9-2*5/3 +7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2)) '
# match2 = re.findall(r'\([^()]+\)',num)
# print(eval(match2[0]))
# print(match2)
# match1 = re.split(r'\(([^()]+)\)',num,1)  #转义括号,分组括号,分组括号中的匹配会在分割列表中保留
# print(match1)

while true:
    print(num)
    result = re.split(r'\(([^()]+)\)',num,maxsplit=1)  #按照第一次出现的最里层的括号进行切割,最里层括号的内容作为分组结果保留在列表中
    if len(result)==3:  #等于3代表有括号
        before = result[0]   # 第一次出现最里层括号前面的字符串
        content = result[1]  #第一次出现最里层括号中的字符串
        after = result[2]    # 第一次出现最里层括号后面的字符串
        new_content = eval(content)
        print(new_content,type(new_content))
        num = ''.join([before,str(new_content),after])  #通过eval函数计算出来的结果,再与前后括号的内容进行拼接,并赋值给变量num,这样num就变成了少了一层括号的新字符串了
    else:
        final = eval(num)
        print(final)
        break

2. import模块导入

import是导入模块的关键字。
模块分为三类:内置模块,标准模块,第三方模块。
模块的导入路径是sys.path中的各个元素,python解释器去sys.path的各个路径去搜索,如果有这个模块则导入成功。

import modulename表示导入某个模块。
from package import modulename as bbb表示从某个库中导入某个模块,并将模块起别名叫bbb,后面使用就用bbb来代替modulename了。尽量使用from来导入模块。
from package import * 表示导入所有的内容。

3. os模块

sys模块是关于python解释器的模块,而os模块是关于操作系统功能的模块。

import os
current_dir = os.getcwd()   #获取当前工作目录,即当前python脚本工作的绝对目录路径。
print(current_dir)
# os.chdir('..')  #改变当前脚本工作目录,相当于shell下的cd,接一个目录作为参数,可以是相对路径,也可以是绝对路径。
print(os.curdir)  # 返回当前目录的字符串名:('.')
print(os.pardir)  #返回当前目录的父目录字符串名:('..')
#os.makedirs(path,mode,exist_ok=false)
# os.makedirs('dir/dir2') #可生成多层递归目录,如果不是绝对路径,则默认在当前目录下创建目录。
# os.removedirs('dir/dir2') #若目录为空,则移除,并递归到上一层目录,如若也空,则删除,依此类推
# os.mkdir('dir')  #创建单层目录,如果不是绝对路径,则默认在当前目录下创建目录
# os.rmdir('dir')  #删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
print(os.listdir('dir'))  #列出指定目录下的所有文件和目录,包括隐藏文件,并以列表形式返回
# os.remove('dir/new text document.txt')  #删除指定文件
#os.rename('oldname','newname') 重命名文件/目录
print(os.stat('dir'))  #获取文件/目录信息
print(os.sep)  #获取操作系统特定的路径分隔符,window是\\,linux是/
print(os.linesep) #当前平台使用的行终止符,win下为'\r\n',linux下为'\n'
print(os.pathsep)  #用于分割文件路径的字符串,即';'
print(os.name)  #显示当前使用平台,win下是nt,linux下是posix
os.system('dir')  #运行shell命令,直接显示
# print(os.environ)  #获取系统环境变量
print(os.path.abspath('../..') ) #返回指定路径的绝对路径,一般参数是相对路径如'.','..'
path_list = os.path.split(r'f:\github\thestudyofpython\studyofpython\pycharm_lanxing\learn_python_from_oldboy\day8_os\osmodule.py')
print(path_list)  #将path分割成目录和文件名二元组返回
abs_par_path=os.path.dirname(r'f:\github\thestudyofpython\studyofpython\pycharm_lanxing\learn_python_from_oldboy\day8_os\osmodule.py')
#返回指定目录的上一级目录的绝对路径值,其实就是split的第一个元素
os.path.basename(r'f:\github\thestudyofpython\studyofpython\pycharm_lanxing\learn_python_from_oldboy\day8_os\osmodule.py')
#返回给定路径的文件名,如果path以/或\\结尾,则返回空值,就是split的第二个元素。
os.path.exists(r'f:\github\thestudyofpython\studyofpython\pycharm_lanxing\learn_python_from_oldboy\day8_os\osmodule.py')
#如果给定路径存在,则返回true,否则是false
os.path.isabs(r'f:dsaf/adf')
#如果给定路径是绝对路径,则返回true.
os.path.isfile(r'f:\13.txt')  #如果路径是一个存在的文件,返回true
os.path.isdir(r'f:/test1')  #如果路径是一个存在的文件夹,返回true
print(os.path.join('f:','test1','test2','123.txt'))  #将路径拼接在一起,形成一个目录。f:test1\test2\123.txt
time1 = os.path.getatime(r'f:\github\thestudyofpython\studyofpython\pycharm_lanxing\learn_python_from_oldboy\day3\int_str_set.py')
#返回path所指向的文件或者目录的最后存取时间戳
import time
print(time.ctime(time1))
time2= os.path.getmtime(r'f:\github\thestudyofpython\studyofpython\pycharm_lanxing\learn_python_from_oldboy\day3\int_str_set.py')
print(time2)
# 返回path所指向的文件或者目录的最后修改时间戳

4. hashlib模块

用于加密相关的操作,代替了md5模块和sha模块,主要提供sha1,sha224,sha256,sha384,sha512,md5算法.
现在常用是md5与sha256.

import hashlib


# md5算法
'''
- update(data): update the hash object with the bytes in data. repeated calls
                 are equivalent to a single call with the concatenation of all
                 the arguments.
 - digest():     return the digest of the bytes passed to the update() method
                 so far as a bytes object.
 - hexdigest():  like digest() except the digest is returned as a string
                 of double length, containing only hexadecimal digits.
 - copy():       return a copy (clone) of the hash object. this can be used to
                 efficiently compute the digests of datas that share a common
                 initial substring.
'''
hash1 = hashlib.md5()  #创建一个md5的哈希对象
hash1.update(bytes('lanxing',encoding='utf-8'))  #update方法是使用字节类型数据去更新哈希对象
print(hash1,type(hash1))
print(hash1.digest(),type(hash1.digest()))  #返回哈希对象的字节类型摘要
print(hash1.hexdigest()) #返回十六进制的哈希值


hash2 = hashlib.sha256()
hash2.update(bytes('lanxing',encoding='utf-8'))
print(hash2.hexdigest())
# 59b304df8872f6f0443d389574796e65160c8a8b4df6073e20168ae82a73187a
hash3 = hashlib.sha256(bytes('lanxing',encoding='utf-8'))  #创建一个sha256的哈希对象,其盐是lanxing
hash3.update(bytes('lanxing',encoding='utf-8'))  #加盐之后,原先对应的哈希值就不一样了。可以防止别人撞库。
print(hash3.hexdigest())
# 590ec4accc861c0feb928f62c221f5b943e17aeda50e43d6d894050cf42de48e
import hashlib

def register(username,passwd):
    '''
    register a new account to the database
    :param username: username , a str
    :param passwd:  password, a str
    :return: true
    '''
    with open('accounts.db','a+',encoding='utf-8') as f:
        ret = hash_passwd(passwd)
        account = '\n'+username+'$'+ret
        f.write(account)
        f.flush()

    return true

def login(username,passwd):
    '''
    check the account to see if they match the account in the database
    :param username: username,a str
    :param passwd: password,a str
    :return: true if matched,false if not.
    '''
    with open('accounts.db','r',encoding='utf-8') as f:
        for line in f:
            data = line.split('$')
            ret = hash_passwd(passwd)
            if data[0]==username and ret == data[1]:
                return true



def hash_passwd(passwd):
    '''
    change the passwd to hexdigest of hash object
    :param passwd: a str
    :return: hexdigest
    '''
    hash1 = hashlib.sha256(bytes('lanxing', encoding='utf-8'))
    hash1.update(bytes(passwd, encoding='utf-8'))
    return hash1.hexdigest()


if __name__=='__main__':
    username = input('enter your name:>>>').strip()
    passwd = input('enter your passwd').strip()
    choice = input('1 to register or 2 to log in:>>>').strip()
    if choice == '1':
        register(username,passwd)
        print('注册成功')
    elif choice=='2':
        if login(username,passwd):
            print('登录成功')
        else:
            print('登录失败')

5. 字符串格式:百分号法与format方法

百分号法是比较老的方式,而format是较新的方法,现在python3中两者共存。

  • 百分号%方法

%[(name)][flags][width].[precision]typecode,其中name,flags,width,precision都是可选的。
name表示key,后面可以通过key:value的形式进行引用。
flags与width经常一起用:
flags表示左右对齐,值有+表示右对齐,空格表示右对齐,-表示左对齐,0表示右对齐,用0补充不足宽度处。
width表达宽度,一般用不着。值是数字。
precision表示精度,值是数字。
typecode常用s(表示字符串),d(表示整数),f(表示浮点数)。必选参数。
如果字符串中有占位符%,要想表示原生的%,必须使用两个%。'%% %.2f' % 3.689

s='i am %(name)s, and my age is %(age)d'%{'name':'lanxing','age':19}
print(s)
# i am lanxing, and my age is 19
s1 = 'i am %(name)+10s, and my age is %(age).2f'%{'name':'lanxing','age':19.6789}
print(s1)
# i am    lanxing, and my age is 19.68
  • format方法

[[fill]align][sign][#][0][width][,][.precision][type]
参数介绍:
python day 8: re模块补充,导入模块,hashlib模块,字符串格式化,模块知识拾遗,requests模块初识
python day 8: re模块补充,导入模块,hashlib模块,字符串格式化,模块知识拾遗,requests模块初识

s1 = ' i am {},age {},sex {}'.format('lanxing',18,'male')
s2 = 'i am {},age {},sex {}'.format(*['lanxing',18,'male'])
s3 = 'i am {0},age{1},really {0}'.format('rich',19)  #format参数的索引值,从0开始
s4 = 'i am {0},age{1},really {0}'.format(*('rich',18))
s5 = 'i am {name},age{age},reall {name}'.format(name='rich',age=18)
s6 = 'i am {name},age{age},reall {name}'.format(**{'name':'rich','age':18})
s7 = 'i am {0[0]},age {0[1]},really{0[2]}'.format([11,22,33],[44,55,66])
s8 = 'i am {:s},age {:d},money {:.2f}'.format('lanxing',18,2689.222)
s9 = "i am {name:s}, age {age:d}".format(**{"name": "seven", "age": 18})
s10 =  "numbers: {:b},{:o},{:d},{:x},{:x}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
s11  = "numbers: {0:b},{0:o},{0:d},{0:x},{0:x}, {0:%}".format(15)
s12  = "numbers: {num:b},{num:o},{num:d},{num:x},{num:x}, {num:%}".format(num=15)

6. 模块知识拾遗

# print(vars())

'''
__name__
__loader__
__doc__
__package__
__spec__
__file__
__builtins__
__cached__
'''
print(__name__) #如果是主文件,__name__==‘__main__',如果是其他文件,则是他的模块名
import str_format as sf
print(sf.__name__)

print(__doc__)  #自身py文件的多行注释
print(sf.__package__ ) #导入py文件所在的文件夹,用.划分文件夹,当前文件是none
print(__file__)  #本身自己文件的绝对路径

print(sf.__cached__)  #缓存:缓存,当前文件没有,导入其他文件才有

# 只有执行自身时,__name__=='__main__',否则等于其模块名,以后主程序都要先加个条件,这样别人导入时,就不会自动执行了。
if __name__=='__main__':
    a = 1
#将某个文件夹路径放入sys.path中,且不怕父文件夹改名
import os,sys

if __name__=='__main__':  #主文件执行时,一定要写这个
    dir1=os.path.dirname(__file__)  #__file__一定要记住是文件自身的绝对路径
    dir2 = os.path.dirname(dir1)  #某个路径的上层目录
    s1 = 'day7_time_sys'
    dir3 =os.path.join(dir2,s1)  #将路径拼接在一起
    print(dir3)
    sys.path.append(dir3)  #将某个路径追加到python解释器的模块搜索路径列表中去

import jsonmodule
  • 安装第三方模块

使用pip安装
第一步:先下载pip。
第二步:将pip的bin目录添加到环境变量中。
第三步:在cmd中运行 pip install modulename

源码安装
第一步:先下载源码。
第二步:解压缩源码。
第三步:在cmd中进入源码目录。
第四步:cmd中执行python setup.py install

7. requests模块初识

urllib,requests是发起http请求,获得请求返回值的模块。

import requests,json

# requests模块,发送http请求,(用python模拟浏览器请求)

response = requests.get('https://www.cnblogs.com/wupeiqi/articles/5484747.html')
# 向指定网址发送请求,返回一个requests.models.response对象
response.encoding = 'utf-8'  #将请求对象的编码设置为utf8
result =response.text  #text就是请求对象的内容,是一个str类型
# result = json.loads(result)  #会报错
print(type(response),result,type(result),sep='\n')