day28

什么是包

包就是模块,也是用来导入的

包的本质就是内含带有.py文件的文件夹

为什么要有包

随着文件越来越大,模块越来越多,模块设计者对模块的管理和维护越来越复杂,因此我们可以使用包来扩展模块的功能.

如何使用包

模块与包

导入模块发生的三件事:

  1. 创建一个模块的名称空间
  2. 执行.py文件,将执行过程中产生的名字存放在名称空间中
  3. 在当前执行文件中放入模块名,这个名字指向模块的名称空间

导入包发生的三件事情:

  1. 创建一个包的名称空间
  2. 由于包是一个文件夹,无法执行包,因此执行包下的.py文件,将执行过程中产生的名字存放在包名称空间中(即包的名称空间存放的名字都是来自.py)
  3. 在当前执行文件中放入包名,这个名字指向包的名称空间

包是含有_\_init__.py的文件夹; 导包就是导入__init__.py

包一定是被当作模块文件导入,模块文件 m1.py/m2.py 的搜索路径以执行文件 包的介绍.py路径为准

导的哪个名称空间的名字就能使用这个名称空间,导的哪个函数名或者变量名就能使用这个函数或者变量

导入包内包

# aaaa/.py
from aaaa import bbb

导入包内包的模块

# bbb/.py
from aaaa.bbb import m3
# aaaa/.py
from aaaa.bbb.m3 import f1
# 包的介绍
import aaaa

aaaa.f1()

绝对导入和相对导入

绝对导入:

from .m1 import *
from .m2 import *

相对导入:

.代表当前被导入文件所在的文件夹

..代表当前被导入文件所在的文件夹的上一级

...代表当前被导入文件所在的文件夹的上一级的上一级

注意事项

  1. 包内所有的文件都是被导入使用的,而不是被直接运行的
  2. 包内部模块之间的导入可以使用绝对导入(以包的根目录为基准)与相对导入(以当前被导入的模块所在的目录为基准),推荐使用相对导入
  3. 当文件是执行文件时,无法在该文件内用相对导入的语法,只有在文件时被当作模块导入时,该文件内才能使用相对导入的语法
  4. 凡是在导入时带点的,点的左边都必须是一个包,import aaa.bbb.m3.f3错误

time模块

时间戳(timestamp)

时间戳表示的是从1970年1月1日00:00:00开始按秒计算 到现在的时间

import time

time_stamp = time.time()
print(time_stamp, type(time_stamp))

格式化的时间字符串(format string)

格式化时间表示的是普通的字符串格式的时间。

# 格式的-是拼接符号
format_time = time.strftime("%Y-%m-%d %X")
print(format_time, type(format_time))

结构化的时间(struct time)

元组共有9个元素共九个元素分别为年,月,日,时,分,秒...

print('本地时区的struct_time:\n{}'.format(time.localtime()))
print('UTC时区的struct_time:\n{}'.format(time.gmtime()))

# 结构化时间的基准时间
print(time.localtime(0))

# 结构化时间的基准时间上增加一年时间
print(time.localtime(3600*24*365))

三种格式时间的转换

结构化时间 , 定义 now_time

now_time = time.localtime()
print(now_time)
# 把结构化时间转换为时间戳格式
print(time.mktime(now_time)) 

# 把结构化时间转换为格式化时间
# %Y年-%m月-%d天 %X时分秒=%H时:%M分:%S秒
print(time.strftime("%Y-%m-%d %X", now_time))

# 把格式化时间化为结构化时间,它和strftime()是逆操作
print(time.strptime('2013-05-20 13:14:52', '%Y-%m-%d %X'))

# 把结构化时间表示为这种形式:'Sun Jun 20 01:00:00 2000'。
print(time.asctime())

datetime模块

用于时间的加减

import datetime

# 返回当前时间
print(datetime.datetime.now())

# 当前时间+3天
print(datetime.datetime.now() + datetime.timedelta(3))

# 当前时间-3天
print(datetime.datetime.now() + datetime.timedelta(-3))

# 当前时间-3小时
print(datetime.datetime.now() + datetime.timedelta(hours=3))

# 当前时间+30分钟
print(datetime.datetime.now() + datetime.timedelta(minutes=30))

# 时间替换
c_time = datetime.datetime.now()
print(c_time.replace(minute=20, hour=5, second=13))

hashlib模块

用于加密

模块特点

  1. 只要使用的hash算法不变,无论校验的内容有多大 , 结果永远都是相同长度的字符串
  2. 叠加性

基本用法

import hashlib

m = hashlib.md5()
m.update('hello'.encode('utf8'))
print(m.hexdigest())

hmac模块

hmac和hashlib相似,但是会有一个加盐(秘钥) , 特点与hashlib相同

基本用法

import hmac

# 注意hmac模块只接受二进制数据的加密
h1 = hmac.new(b'hash')
h1.update(b'hello')
h1.update(b'world')
print(h1.hexdigest())

h2 = hmac.new(b'hash')
h2.update(b'helloworld')
print(h2.hexdigest())

typing模块

作用

  1. 类型检查,防止运行时出现参数和返回值类型不符合。
  2. 作为开发文档附加说明,方便使用者调用时传入和返回参数类型。
  3. 该模块加入后并不会影响程序的运行,不会报正式的错误,只有提醒。

基本使用

from typing import List, Tuple, Dict

# 指定函数参数的数据类型
def add(a: int, string: str, f: float,
        b: bool) -> Tuple[List, Tuple, Dict, bool]:
    list1 = list(range(a))
    tup = (string, string, string)
    d = {"a": f}
    bl = b
    return list1, tup, d, bl

print(add(5, "hhhh", 2.3, False))

常用类型

整型、长整形、浮点型布尔型、字符串类型列表、元组、字典、集合可迭代类型、迭代器类型生成器类型

request模块

常用于爬虫 , 作用是模拟浏览器对url发送请求,拿到数据

使用方法

import requests

response = requests.get('https://www.baidu.com')
data = response.text
print(data)

# 常与re模块连用

re模块

re模块 , 即正则表达式 , 本身是一种小型的、高度专业化的编程语言,它并不是Python的一部分

作用

从大的字符串中挑选出 具有某种形状特点的字符串

常用元字符

^ 以...开头

s = 'abcdabc' 
res = re.findall('^ab', s)
print(res)  

$ 以...结尾

s = 'abcdabc'
res = re.findall('bc$', s)
print(res)  

. 任意字符

s = 'abc红abc'
res = re.findall('abc.', s)
print(res)  

\d 数字

s = 'skld2342ljk'
res = re.findall('\d', s)
print(res) 

\D 非数字

s = 'skld2342ljk'
res = re.findall('\D', s)
print(res)

\w 非空字符,即数字字母下划线

s = 'skld_2你3 42ljk'
res = re.findall('\w', s)
print(res)

\W 空字符,包括空格 换行

s = 'skld_23 42ljk'
res = re.findall('\W', s)
print(res)

\s 空字符,包括空格 换行

s = 'skld_23 42ljk'
res = re.findall('\s', s)
print(res)

\S 非空字符,即数字字母下划线

s = 'skld_23 42ljk'
res = re.findall('\S', s)
print(res)

+前面的一个字符至少1个 [1,正无穷)

s = 'abcddabdabcdd abcd abc'
print(re.findall('abcd+', s))

? 前面的一个字符0-1个 前一个字符[0,1] 最大只有一个

s = 'abcddddd abcd abc ab'
print(re.findall('abcd?', s))

*前面的一个字符至少0个 前一个字符[0,正无穷)

s = 'abcddddd abcd abc ab'
print(re.findall('abcd*', s))

[] 中括号内的都可以 , 但是只占一个位置

s = 'abc bbc cbc dbc abcd '
print(re.findall('[abc]bc', s))

[^] 中括号的都不可以

s = 'abc bbc cbc dbc'
print(re.findall('[^abc]bc', s))

| 或 满足就打印 , 一个或者两个三个

s = 'abc bbd dbc'
print(re.findall('abc|bbc', s))

{2} 前面的字符重复2个

s = 'abccabc abccc'
print(re.findall('abc{2}', s))

{1,2} 前面的字符重复1-2个 区间是[1,2]

s = 'abccabc abccc'
print(re.findall('abc{1,2}', s))

贪婪模式

Python里数量词默认是贪婪的,总是尝试匹配尽可能多的字符 , 一定要找到最后 才停止

.(任意字符)*(0-无穷个)

s = 'abcdefgbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbg'
print(re.findall('a.*g', s)

非贪婪模式

非贪婪的则相反,总是尝试匹配尽可能少的字符 , 找到一个就停止并返回

.(任意字符)*(0-无穷个)?(让他进入非贪婪模式)

s = 'abcdefgbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbg'
print(re.findall('a.*?g', s))

re的常用函数

findall

最常用 推荐使用 直接在函数内部书写匹配规则

import re
a = re.findall("匹配规则", "这个字符串是否有匹配规则的字符")
print(a)

compile

写一个特定的规则模板

# 定义邮箱、手机号匹配规则,直接调用
email_pattern = re.compile('\w+@\w+.com')
phone_patter = re.compile('\d{13}')
print(re.findall(email_pattern, s))

match

从字符串开头找一个,找得到就不找了 ;找不到报错

s = 'ab abcddd abc'
res = re.match('abcd*', s)
print(res.group())

搜索,从整个内容中匹配,只找一个,找不到报错

s = 'ab abcddd abc'
res = re.search('abcd*', s)
print(res.group())

split

切割,相当于字符串的split

s = 'ab23423abcddd234234abcasdfjlasjdk234l23lk4j2kl34kl25k3j2kl3j5lkj'
print(re.split('\d+', s))

sub

替换,相当于字符串的replace

s = 'ab23423abcddd234234abcasdfjlasjdk234l23lk4j2kl34kl25k3j2kl3j5lkj'
print(re.sub('\d+', ' ', s))

subn

替换,会返回替换的次数

s = 'ab23423abcddd234234abcasdfjlasjdk234l23lk4j2kl34kl25k3j2kl3j5lkj'
print(re.subn('\d+', ' ', s))

re模块补充

re.S 会让.匹配换行符

a = '''asdfhellopass:
    worldaf
    '''
b = re.findall('hello(.*?)world', a)
c = re.findall('hello(.*?)world', a, re.S)
print(b)
# []

print(c)

. 不匹配换行

s = '''abc
abcabc*abc
'''
print(re.findall('abc.abc', s))  

print(re.findall('abc.abc', s, re.S))  

分组 --> 只要括号里的(...)

s = 'abc abcd abcdd'
print(re.findall('a(.)c(d)', s))

有名分组

s = 'abc abcd abcdd'
print(re.search('a(?P<name>.)c(?P<name2>d)', s).groupdict())
posted @ 2019-09-28 23:52  Isayama  阅读(145)  评论(0编辑  收藏  举报