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

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]
参数介绍:
参数
参数

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模块初识

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

猜你喜欢

转载自www.cnblogs.com/lanxing0422/p/pythonday8.html