Loading

python基础5--模块

1、模块分类

  1. 内置模块-----python内部提供的功能

  2. 第三方模块-----下载/安装/使用

    # 把pip.exe 所在的目录添加到环境变量中。
    pip install 要安装的模块名称  # pip install xlrd
    # 临时更换pip源
    pip install some-package==版本 -i https://mirrors.aliyun.com/pypi/simple/
    # 从文件安装
    pip install -r requirements.txt
    # 导出到文件
    pip freeze -r requirements.txt
    # 卸载模块
    pip uninstall Package
    # 另一种安装方式
    python -m pip install Package
    
  3. 自定义模块

  • 什么是模块?

    py文件,写好了的,对程序员直接提供某方面功能的文件,公共方法功能。

  • 什么是包?

    • 文件夹 存储了多个py文件的文件夹
    • 如果导入的是一个包,这个包里的模块默认是不能用的
    • 导入一个包相当于执行__init__ py文件中的内容
  1. 导入模块方式
import module
from module.xx.xx import xx
from module.xx.xx import xx as rename 
from module.xx.xx import *

2、内置模块

1. sys

python解释器相关的数据。

  • sys.getrefcount , 获取一个值的引用计数

  • sys.getrecursionlimit , python默认支持的递归数量

  • sys.stdout.write --> print

  • sys.exit(0)退出程序

sys.argv

获取用户执行脚本时,传入的参数。得到的是一个列表,第一个元素是脚本文件

# 删除用户执行脚本传入的目录
import sys
import shutil
path = sys.argv[1]
shutil.rmtree(path)

sys.path

默认Python去导入模块时,会按照sys.path中的路径挨个查找。

# 将当前项目根目录加入sys.path,方便模块导入
import os,sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)

sys.modules

sys.modules是一个全局字典,该字典是python启动后就加载在内存中。每当程序员导入新的模块,sys.modules都将记录这些模块。字典sys.modules对于加载模块起到了缓冲的作用。当某个模块第一次导入,字典sys.modules将自动记录该模块。当第二次再导入该模块时,python会直接到字典中查找,从而加快了程序运行的速度。字典sys.modules具有字典所拥有的一切方法,可以通过这些方法了解当前的环境加载了哪些模块

常用sys.modules[__name__]获取该文件对象,反射获取文件中任意内容

import sys

def func():
    pass

ret=sys.modules
print(getattr(sys.modules[__name__],'func'))

2、os

和操作系统相关的数据。

  • os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False

  • os.stat('xx.mp4').st_size 获取文件大小

  • os.path.getsize() 获取文件大小

  • os.path.abspath() 获取一个文件的绝对路径

  • os.path.basename() 获取文件名

  • os.path.sep 路径分隔符

    import os
    v = os.path.abspath(__file__)
    print(v) # D:\code\project_menu\bin\run.py
    
  • os.path.dirname ,获取路径的上级目录

    import os
    v = os.path.abspath(__file__)
    print(os.path.dirname(v)) # D:\code\project_menu\bin
    
  • os.path.join ,路径的拼接 ,根据不同操作系统加分隔符

    import os
    path = r"D:\code\project_menu\bin"
    v = 'n.txt'
    result = os.path.join(path,v)
    print(result)
    result = os.path.join(path,v,v,v)
    print(result)
    
  • os.listdir , 查看一个目录下所有的文件及文件夹名字【第一层】

    import os
    result = os.listdir(r'D:\code\project_menu')
    print(result)
    # ['.idea', 'bin', 'conf', 'db', 'lib', 'log', 'log.txt', 'src']    
    
  • os.walk , 查看一个目录下所有的文件【所有层】

    import os
    path=r'D:\code\project_menu'
    for root, dirs, files in os.walk(path):
        # root正在查看的目录  dirs此目录下的文件夹  files此目录下的文件
        for file in files:
            abspath = os.path.join(root,file)
            print(abspath)
    
  • os.makedirs,创建目录和子目录

    import os
    file_path = r'D:\code\project_menu\log\log1.log'
    
    file_folder = os.path.dirname(file_path)
    if not os.path.exists(file_folder):
        os.makedirs(file_folder)
    
    with open(file_path,mode='w',encoding='utf-8') as f:
        f.write('hello')
    
  • os.rename(src, dst),重命名

    该方法 可以重命名 文件 和目录,
    如果 src参数 对应文件或目录,不存在,会保错,
    如果 dst 参数 对应文件或目录,已经存在,也会报错

  • os.system() 执行系统命令

    import os
    os.system('cd /usr/local && mkdir aaa.txt')
    # 或者
    os.system('cd /usr/local ; mkdir aaa.txt')
    
  • os.rmdir() 只能删除空文件夹

补充

转义

v1 = r"D:\code\s21day14\n1.mp4"  (推荐)
print(v1)

v2 = "D:\\code\\s21day14\\n1.mp4"
print(v2)

工作目录

print(os.getcwd())
print(__file__)
# D:\code\project_menu\bin
# D:/code/project_menu/bin/run.py

进度条

import time
for i in range(100):
	msg = '进度条跑到%s%%\r' %i # \r 光标回到当前行的起始位置(不是覆盖.,是清空)
	print(msg , end = '')
	time.sleep(0.5) # 暂停0.5s后再运行
import os  
# 1. 读取文件大小(字节)
file_size = os.stat('xx.mp4').st_size  
# 2.一点一点的读取文件
read_size = 0
with open('xx.mp4',mode='rb') as f1,open('a.mp4',mode='wb') as f2:
    while read_size < file_size:
        chunk = f1.read(1024) # 每次最多去读取1024字节
        f2.write(chunk)
        read_size += len(chunk)
        val = int(read_size / file_size * 100)
        print('%s%%\r' %val ,end='')

3、shutil

import shutil

shutil.rmtree( src ) 递归删除一个目录以及目录内的所有内容
shutil.move( src, dst)  移动文件或重命名 

生成压缩文件:

shutil.make_archive(base_name, 'gztar', root_dir, [base_dir)

  • base_name : 创建的目标文件名,包括路径,减去任何特定格式的扩展。
  • format : 压缩包格式。”zip”, “tar”, “bztar”或”gztar”中的一个。
  • root_dir : 需要打包的文件夹路径。打包完成时存储在上一级目录。
  • base_dir : 使用后会将base_dir作为路径,解压后有个有层级的文件夹,而仅非只有单独的打包内容。

解压文件:

shutil.unpack_archive(filename[, extract_dir[, format]])

  • filename是压缩文档的完整路径
  • extract_dir是解压缩路径,默认为当前目录。
  • format是压缩格式。默认使用文件后缀名代码的压缩格式。”zip”, “tar”, “bztar”或”gztar”中的一个。

4、json

json是一个特殊的字符串。 【长的像列表/字典/字符串/数字/真假】

# json格式 :
    1.所有的字符串都是双引号
    2.最外层只能是列表或者字典
    3.只支持 int float str list dict bool
    4.存在字典字典的key只能是str
    5.不能连续load多次
  • dumps序列化 & load反序列化
import json
# 序列化,将python的值转换为json格式的字符串。
v = [12,3,4,{'k1':'v1'},True,'yhp']
v1 = json.dumps(v)
print(v1)

# 反序列化,将json格式的字符串转换成python的数据类型
v2 = '["yhp",123]'
print(type(v2))
v3 = json.loads(v2)
print(v3,type(v3))

json.dumps 序列化时对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False:

v = {'k1':'yhp','k2':'杰克'}
import json
val = json.dumps(v,ensure_ascii=False)
print(val)
  • dump序列化并写入文件

    import json
    v = {'k1':'yhp','k2':'杰克'}
    f = open('x.txt',mode='w',encoding='utf-8')
    json.dump(v,f,ensure_ascii=False)
    f.close()
    
  • load从文件读取并反序列化

    import json
    f = open('x.txt',mode='r',encoding='utf-8')
    res=json.load(f)
    f.close()
    print(res)
    

5、pickle

  • json,优点:所有语言通用;缺点:只能序列化基本的数据类型 list/dict/int...
  • pickle,优点:python中所有的东西都能被他序列化(socket对象);缺点:序列化的内容只有python认识。

用法同json

6、time&datetime

UTC/GMT:世界时间

本地时间:本地时区的时间。

  • time模块

    • time.time() ,时间戳:从1970-1-1 00:00 起始 #1590660513.8918743
    • time.sleep(10),等待秒数。
    • time.timezone
  • datetime模块

    import time
    from datetime import datetime,timezone,timedelta
    
    # 获取datetime格式时间
    
    v1 = datetime.now() # 当前本地时间
    print(v1)
    tz = timezone(timedelta(hours=7)) # 当前东7区时间
    v2 = datetime.now(tz)
    print(v2)
    v3 = datetime.utcnow() # 当前UTC时间
    print(v3)
    
    
    # 把datetime格式转换成字符串 
    v1 = datetime.now()
    print(v1,type(v1))
    val = v1.strftime("%Y-%m-%d %H:%M:%S")
    print(val)
    
    # 字符串转成datetime 
    v1 = datetime.strptime('2011-11-11','%Y-%m-%d')
    print(v1,type(v1))
    
    #  datetime时间的加减 
    v1 = datetime.strptime('2011-11-11','%Y-%m-%d')
    v2 = v1 - timedelta(days=140)
    date = v2.strftime('%Y-%m-%d')
    print(date)
    
    # 时间戳和datetime关系 
    ctime = time.time()
    print(ctime)
    v1 = datetime.fromtimestamp(ctime)
    print(v1)
    
    v1 = datetime.now()
    val = v1.timestamp()
    print(val)
    

7、 hashlib

  • 将指定的 “字符串” 进行加密。
import hashlib

def get_md5(data):
    #可以选择加盐 obj = hashlib.md5("salt".encode('utf-8'))
    obj = hashlib.md5()
    obj.update(data.encode('utf-8'))
    result = obj.hexdigest()
    return result

val = get_md5('123')
print(val)
  • 校验文件一致性,分多次update,最终结果相同
import hashlib,os
path1 = r'xxx.mp4'
path2 = r'xxxxx.mp4'


def file_md5(path):
    size = os.path.getsize(path)
    md5 = hashlib.md5()
    with open(path,mode='rb') as f:
        while size>1024:
            content = f.read(1024)
            md5.update(content)
            size -=1024
        else:
            content = f.read(size)
            md5.update(content)
            size = 0
    return md5.hexdigest()

print(file_md5(path1)== file_md5(path2))
import hashlib
md5 = hashlib.sha1('盐'.encode())
md5.update(b'str')
print(md5.hexdigest())

8、random

import random
print(random.uniform(1,5))          #返回随机实数
print(random.randint(1,5))          #返回随机整数
print(random.choice([1,2,3,4,5]))   #返回列表随机数
print(random.sample([1,2,3,4],3))   #从列表随机抽取3个
l=[1,2,3,4]
random.shuffle(l)                   #随机打乱列表
print(l)
# 4.005596196642935
# 3
# 2
# [4, 3, 1]
# [2, 1, 4, 3]

9、 functools

functools.reduce()
functools.partial()
functools.wraps()

10、 re

到底什么是正则表达式(regex)?

在编写处理字符串的程序或网页时,经常有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。

在线工具

常用元字符

\d	表示所有的数字
\w	字母/数字/下划线
\s	空白(空格/换行符/制表符)
\t	匹配制表符 Tab
\n	匹配换行符
.	表示除了换行符之外的任意内容
\D	表示所有的非数字
\W	表示除 数字字母下划线之外的所有字符
\S	表示非空白
[]	  	字符组 :只要在中括号内的所有字符都是符合规则的字符
[^xyz]	非字符组 :只要在中括号内的所有字符都是不符合规则的字符
^	表示一个字符的开始
$	表示一个字符的结束
|	表示或,注意,如果两个规则有重叠部分,总是长的在前面,短的在后面
()	表示分组,给一部分正则规定为一组,|这个符号的作用域就可以缩小了

[\d\D] [\W\w] [\S\s] 匹配所有一切字符

常用限定符(量词)

代码/语法 说明
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
重复n次
重复n次或更多次
重复n到m次

匹配一个整数或者小数 \d+.\d+|\d+ \d+.?\d* \d+(.\d+)?

# 以a开头,由至少一个字母组成的字符串
# ^a[a-zA-Z]+
# ^a[a-zA-Z]*

# 以1开头,中间3-5个数字,如果中间位置超过5个数字,则整个字符串不匹配
# ^1\d{3,5}$

贪婪匹配

默认采用回溯算法,贪婪匹配,总是会在符合量词条件的范围内尽量多匹配.

adljdkjsljdlj

<.+> 会匹配到整个字符串,而不是

惰性匹配

总是匹配符合条件范围内尽量小的字符串

格式: 元字符 量词 ? x

表示按照元字符规则在量词范围内匹配,一旦遇到x就停止

# 身份证号
# 15位  全数字 首位不为0
# 18位  前17位全数字 首位不为0  最后一位可能是x和数字
# [1-9](\d{14}|\d{16}(\d|x))
# [1-9](\d{16}[\dx]|\d{14})
# [1-9]\d{14}(\d{2}[\dx])?

表达式中转义符

正则表达式中的转义符在python的字符串中也刚好有转义的作用,但是正则表达式中的转义符和字符串中的转义符并没关系,且还容易有冲突,为了避免这种冲突,我们所有的正则都以在工具中的测试结果为结果,然后只需要在正则和待匹配的字符串外面都加r即可.

  • \d \s \w \t \n→python字符串中
  • 匹配()[]{}\d等,需要加\转义

re正则模块

  • re.findall('正则表达式',字符串)
    匹配字符串中所有符合规则的项,并返回一个列表,如果未匹配到返回空列表

  • re.search('正则表达式',字符串)

    匹配字符串中满足条件的第一项,返回一个对象,用group方法取值;如果不能匹配上返回None,group方法会报错.

if ret:
    print(ret.group()) # 如果是对象,那么这个对象内部实现了group,所以可以取值
                       # 如果是None,那么这个对象不可能实现了group方法,所以报错
  • ret.match('正则表达式',字符串)

    会从头匹配字符串中取出从第一个字符开始是否符合规则,如果符合,就返回对象,用group取值,如果不符合,就返回None

    match = search + ^正则

  • re.finditer('正则表达式',字符串)

    返回一个迭代器,迭代出来的每一项都是一个对象,然后group取值

    在查询的结果超过1个的情况下,能够有效的节省内存,降低空间复杂度,从而也降低了时间复杂度

  • re.compile('正则表达式')

    正则表达式编译成python语言,供多次使用

    ret = re.compile('\d3')
    r1=ret.search("djasjd5a646")
    
  • re.split()

    re.split('\d\d','alex83wusir74taibai')	  #不保存被分割的内容 [,1]第几个分割
    re.split('\d(\d)','alex83wusir74taibai')  # 默认自动保留分组中的内容
    
  • re.sub('正则表达式',替换内容,字符串,[序号])
    返回字符串

  • re.subn('正则表达式',替换内容,字符串,[序号])
    返回元组(替换后字符串,替换个数)

分组

  • 分组命名
    (?P<组名>正则)

  • 引用分组
    (?P=组命)

  • findall和分组

    • 优先显示分组中的内容,其他内容内容返回空字符串""
    • (?:)取消这个分组的优先⭐ ,量词为了约定多个字符加括号,会产生此情况.
    import re
    ret = re.findall('\d+(\.\d+)?','21.234+2')
    print(ret)
    #运行结果:['.234', '']
    
    import re
    ret = re.findall('\d+(?:\.\d+)?','21.234+2')
    print(ret)
    #运行结果:['21.234', '2']
    

小技巧:有的时候我们想匹配的内容包含在不相匹配的内容当中,这个时候只需要把不想匹配的先匹配出来,再通过手段去掉.

import re
ret=re.findall(r"\d+\.\d+|(\d+)","1-2*(60+(-40.35/5)-(-4*3))")
print(ret)
ret.remove('')
print(ret)
#运行结果:
#['1', '2', '60', '', '5', '4', '3']
#['1', '2', '60', '5', '4', '3']
  • split和分组
    会保留分组中本来应该被切割掉的内容
  • search和分组
    通过索引取 obj.group(1)
    通过组名取 obj.group('组名')
# 1.找出<h1>123fh</h1><h2>hado</h2>中所有标签内的字符串   爬虫
import re
ret = re.findall('<.*?>(.*?)<.*?>','<h1>123fh</h1><h2>hado</h2>')
print(ret)

# 2.找出四则运算表达式中的第一个乘除法
# \d*\d|\d/\d
# \d+(\.\d+)?[*/]\d(\.\d+)?
# \d+(\.\d+)?[*/]-?\d(\.\d+)?
import re
ret = re.search('\d+(\.\d+)?[*/]-?\d(\.\d+)?', '2-3*-5/6')
print(ret.group())

# 3.检测用户输入的内容是否是一个合法的身份证号     网页的合法输入(手机号码 qq号码 银行卡号 邮箱地址)
# '^[1-9]\d{14}(\d{2}[\dx])?$'
import re
inp = input('>>>').strip()
re.match('[1-9]\d{14}(\d{2}[\dx])?$', inp)  # 首选
re.search('^[1-9]\d{14}(\d{2}[\dx])?$', inp)
re.findall('^[1-9]\d{14}(\d{2}[\dx])?$', inp)
ret=re.findall(pattern,info,re.S) #允许.匹配下一行
使'.'特殊字符匹配任何字符,包括换行 ;如果没有此标志, '.'将匹配任何内容除换行符。

collections

在内置数据类型(dict,list,set,tuple)的基础上,collections 模块还提供了几个额外的数据类型:

1.namedtuple:生成可以使用名字来访问元素内容的tuple

2.deque:双向队列(两头都可进可出,但是不能取中间的值),可以快速的从另外一侧追加和推出对象

3.Counter:计数器,主要用来计数

4.OrderedDict:有序字典

5.defaultdict:带有默认值的字典

1、namedtuple

之前我们获取元组中的值,我们通过索引来取,但是通过可命名的元组,我们可以通过名称来获取值。

from collections import namedtuple # 可命名元组
# namedtuple('名称',‘属性list’)
Circle = namedtuple('Circle', ['x', 'y', 'r'])#用坐标和半径表示一个圆
c=Circle(2,3,5)
print('坐标:({},{}),半径:{}'.format(c.x,c.y,c.r))

2、deque

  1. 单向队列queue
import queue
q = queue.Queue()
q.put(11)
print(q.get())
  1. 双向队列
from collections import deque

q = deque(['a', 'b', 'c'])
# 添加元素
q.append('d')
print(q)
# 从左边添加
q.appendleft('k')
print(q)
# 删除元素
q.pop()
print(q)
# 从左边删除元素
q.popleft()
print(q)

3、OrderedDict

from collections import OrderedDict #有序字典

info = OrderedDict()
info['k1'] = 123
info['k2'] = 456

print(info.keys())
print(info.values())
print(info.items())
# out:
# odict_keys(['k1', 'k2'])
# odict_values([123, 456])
# odict_items([('k1', 123), ('k2', 456)])

4、defaultdict

当我使用普通的字典时,用法一般是dict={},添加元素的只需要dict[element] =value即,调用的时候也是如此,dict[element] = xxx,但前提是element字典里,如果不在字典里就会报错。

defaultdict的作用是在于,当字典里的key不存在但被查找时,返回的不是keyError而是一个默认值

defaultdict接受一个工厂函数factory_function作为参数,这个factory_function可以是list、set、str等等,作用是当key不存在时,返回的是工厂函数的默认值,比如list对应[ ],str对应的是空字符串,set对应set( ),int对应0。

from collections import defaultdict

dict1 = defaultdict(int)
dict2 = defaultdict(set)
dict3 = defaultdict(str)
dict4 = defaultdict(list)
dict1[2] ='two'

print(dict1[1])
print(dict2[1])
print(dict3[1])
print(dict4[1])

0
set()

[]

还可以自己定义:

from collections import defaultdict
dd = defaultdict(lambda: 'N/A')
dd['key1'] = 'abc'
print(dd['key1']) # key1存在

print(dd['key2']) # key2不存在,返回默认值

3、常用第三方模块

posted @ 2019-04-02 21:15  陌路麒麟  阅读(183)  评论(0编辑  收藏  举报