python ca模块_python学习之模块-模块(五)

5.10 包

5.10.1 包的概念

【官网解释】

Packages are a way of structuring Python’s module namespace by using “dotted module names”

包是一种通过使用‘.模块名’来组织python模块名称空间的方式。

具体的:包就是一个包含有__init__.py文件的文件夹,所以其实我们创建包的目的就是为了用文件夹将文件/模块组织起来

【强调】:

在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错

创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包的本质就是一种模块

【创建包时发生的三件事】:

将该包内 __init__py文件加载到内存.

创建一个以该包 命名的名称空间.

通过 包名. 的方式引用__init__里的所有的名字.

5.10.2 import导入

这种方法不常用,但要了解

1 import glance.db.models

2 glance.db.models.register_models('mysql')

示例练习:

import aaa

# 1. 在执行文件写入 import aaa

# 2. aaa的 __init__ 里面 写 from aaa import m1

# 3. 然后在执行文件 aaa.m1.a

# print(aaa.m1.a)

5.10.3 from ... import ...导入

from a.b.c import d

【注意】from后import导入的模块,必须是明确的一个不能带点,否则会有语法错误,如:from a import b.c是错误语法

from与import 之间的a.b.c 中的b必须是包

# from ... import ...练习

# 通过这种方式不用设置__init__文件

# from aaa import m1

# m1.func()

# from aaa.bbb.m2 import func1 #aaa外包,bbb内包

# func1()

# from aaa.bbb import m2

# m2.func1()

# from a.b.c import d

# c的. 的前面一定是包

# import 的后面一定是名字,并且不能 再有点

【包里嵌包】:如果要把内层包里的模块加到外层__init__里,需要用

from wrapper import inner # wrappe外包名,inner内包名

# 举例

# 如何在当前文件中,引用 aaa包的bbb包.

# 1. 在执行文件写入 import aaa

# 2. aaa的 __init__ 里面 写 from aaa import bbb

# 3. 然后在执行文件 aaa.bbb

# print(aaa.bbb)

# 如何在当前文件中,引用 aaa包的bbb包 的 变量 name.

# 1. 在执行文件写入 import aaa

# 2. aaa的 __init__ 里面 写 from aaa import bbb

# 3. 然后在执行文件 aaa.bbb

# print(aaa.bbb)

# 如何在当前文件中,引用 aaa包的bbb包 的 mb文件的函数func.

# 1. 在执行文件写入 import aaa

# 2. 在aaa包的__init__ 写上 from aaa import bbb (这样写 bbb包的__init__里面所有的名字都能引用)

# print(aaa.bbb.name)

# 3. 在bbb包的__init__ 写上 from aaa.bbb import mb

# aaa.bbb.mb.func3()

5.10.4 绝对导入和相对导入

​最顶级包glance是写给别人用的,然后在glance包内部也会有彼此之间互相导入的需求,这时候就有绝对导入和相对导入两种方式:

绝对导入:以glance作为起始

相对导入:用 . 或者 .. 的方式最为起始(只能在一个包中使用,不能用于不同目录内)

例如:我们在glance/api/version.py中想要导入glance/cmd/manage.py

【总结】

绝对导入与相对导入

# 绝对导入: 以执行文件的sys.path为起始点开始导入,称之为绝对导入

# 优点: 执行文件与被导入的模块中都可以使用

# 缺点: 所有导入都是以sys.path为起始点,导入麻烦

# 相对导入: 参照当前所在文件的文件夹为起始开始查找,称之为相对导入

# 符号: .代表当前所在文件的文件加,..代表上一级文件夹,...代表上一级的上一级文件夹

# 优点: 导入更加简单

# 缺点: 只能在导入包中的模块时才能使用

#注意:

1. 相对导入只能用于包内部模块之间的相互导入,导入者与被导入者都必须存在于一个包内

2. attempted relative import beyond top-level package # 试图在顶级包之外使用相对导入是错误的,言外之意,必须在顶级包内使用相对导入,每增加一个.代表跳到上一级文件夹,而上一级不应该超出顶级包

【注意】当对包的命名进行了更新,但是很多项目已经沿用了老的名称,可以使用import 新名称 as 老名称在项目中起别名,就可以解决

5.11 collection模块

在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。

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

2.deque: 双端队列,可以快速的从另外一侧追加和推出对象

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

4.OrderedDict: 有序字典

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

# namedtuple 带名称的元组

from collections import namedtuple

point = namedtuple('point',['x','y'])

p = point(1,2)

print(p)

print(p.x)

# deque双端列表

from collections import deque

q = deque([1,2,3,4,5])

q.appendleft('d')

print(q)

q.popleft()

print(q)

# OrderDict 有序字典

from collections import OrderedDict

d = OrderedDict([('1','a'),('2','b'),('3','c')])

print(d)

#counter计数器

from collections import Counter

c = Counter('asdsadgasdasdasfsgfasgf')

print(c) #生成一个字典,里边存放的是每个字母已经弃数量

# defaultdict

# 有如下值集合 [11,22,33,44,55,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中,即: {'k1': 大于66 , 'k2': 小于66}

#普通版

li = [11,22,33,44,55,77,88,99,90]

result = {}

for row in li:

if row > 66:

if 'key1' not in result:

result['key1'] = []

result['key1'].append(row)

else:

if 'key2' not in result:

result['key2'] = []

result['key2'].append(row)

print(result)

#defaultdict版

from collections import defaultdict

values = [11, 22, 33,44,55,77,88,99,90]

my_dict = defaultdict(list)

for value in values:

if value>66:

my_dict['k1'].append(value)

else:

my_dict['k2'].append(value)

print(my_dict)

5.12 re模块

​正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

5.12.1 元字符

元字符

匹配内容

\w

匹配字母(包含中文)或数字或下划线

\W

匹配非字母(包含中文)或数字或下划线

\s

匹配任意的空白符

\S

匹配任意非空白符

\d

匹配数字

\D

p匹配非数字

\A

从字符串开头匹配

\z

匹配字符串的结束,如果是换行,只匹配到换行前的结果

\n

匹配一个换行符

\t

匹配一个制表符

^

匹配字符串的开始

$

匹配字符串的结尾

.

匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。

[...]

匹配字符组中的字符

[^...]

匹配除了字符组中的字符的所有字符

*

匹配0个或者多个左边的字符。

+

匹配一个或者多个左边的字符。

匹配0个或者1个左边的字符,非贪婪方式。

{n}

精准匹配n个前面的表达式。

{n,m}

匹配n到m次由前面的正则表达式定义的片段,贪婪方式

a|b

匹配a或者b。

()

匹配括号内的表达式,也表示一个组

5.12.2 匹配模式

import re

#单个字符匹配

print(re.findall('\d\d','12a34567890 alex *(_'))

print(re.findall('\w','太白jx 12*() _'))

print(re.findall('\d','1234567890 alex *(_'))

print(re.findall('\Ahel','hello 太白金星 -_- 666'))

print(re.findall('\n','hello \n 太白金星 \t*-_-*\t \n666'))

print(re.findall('.','da\nsdasda\nsdf231\t2314!#!@#!@'))

print(re.findall('hh$','dajqwdadnhhldsdoashhdosasdhh'))

# 元字符匹配

# . 匹配任意一个字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符

print(re.findall('a.b','ab aacb a*b a2b a牛ab a\nb')) #以a开头,以b结尾中间必须有一个字符

print(re.findall('a..b','ab aacb a*b a2b a牛ab a\nb',re.DOTALL)) #以a开头,以b结尾中间必须有两个字符

# ?匹配0个或1个由左边字符定义的片段

print(re.findall('a?b', 'ab aab abb aaaab a牛b aba**b')) #要么有一个a要么没有a

# * 匹配0个或多个左边字符表达式,满足贪婪算法

print(re.findall('a*b','ab aab aaab abbbbb')) #以b结尾,前边有多少个a都无所谓

print(re.findall('ab*','ab cacacb aaab abbbbb')) #比较前后两个字符,必须要以a开头,结尾可以是1个或者0个b

print(re.findall('b*','ab aab aaab abbbbb')) #一个字符一个字符的比较,是b输出,不是b跳过

# + 匹配1个或者多个左边字符的表达式,满足贪婪算法

print(re.findall('a+b',' b ab aab acaab aaab abbb')) #以b结尾,前边可以有一个甚至多个a

print(re.findall('ca+b',' cb ab aab acaab aaab cabbb')) #以b结尾,前边可以有一个甚至多个ca组合

print(re.findall('a+bc',' cbc abc aabc acaab aaab cabbbc')) #以bc结尾,前边可以有一个甚至多个a组

# {n,m}匹配n个至m个左边字符表达式,满足贪婪算法

print(re.findall('a{2,4}b','ab aab aaab aaaaabb'))

# .* 组合,贪婪匹配,从头到尾

print(re.findall('a.*b','ab aab a*()b aasbdsdsdsb')) #以a开头,以b结尾,中间可以有任意字符,ab中间如果还有ab以最外层的ab为准

# .*? 此时的?不是对左边的字符进行0次或者1次的匹配,

# 而只是针对.*这种贪婪匹配的模式进行一种限定:告知他要遵从非贪婪匹配 推荐使用!

print(re.findall('a.*?b','ab aab a*()b aasbdsadsdsb'))

# 练习,寻找_zs结尾的元素

s = '皇子_zs 赵信_zs 盖伦_zs 凯特琳_adc 慎_rz'

print(re.findall('\w*_zs',s))

print(re.findall('\w+_zs',s))

#输出时间

s1 = '''

时间就是1995-04-27,2005-04-27

1999-04-27 德玛西亚

赵信 1980-04-27:1980-04-27

2018-12-08

'''

print(re.findall('\d{4}-\d{2}-\d{2}',s1))

# 匹配一个qq账号 10000开始 第一个元素规定就是非零数字,后面的是随意的数字长度大于5位.

print(re.findall('[1-9][0-9]{4,}','12335345 3453453453 45345123123 0432040320 4324'))

5.12.3 重要语法

re 的匹配语法

re.match 从头开始匹配

re.search 匹配包含

re.findall 把所有匹配到的字符放到以列表中,返回列表

re.split 以匹配到的字符当作列表分隔符

re.sub 匹配字符以替换

re.fullmatch 全部匹配

re.match (pattern,string,flages = 0)

​从起始位置开始根据模型去字符串中匹配指定的内容,匹配单个

pattern 正则表达式

string 要匹配的字符串

flags 标志位,用于控制正则表达式的匹配了方式

falgs标志位

re.I(re.IGNORECASE)忽略大小写(括号内是完整写法,下同)

M(MULTILINE):多行模式,改变'^'和'$'的行为

S(DOALL):改变 . 的行为,make the '.' special character match any character at all ,including a newline ;without this flag, '.' will match anthing except a newline.

x(re.VERBOSE) 给表达式写注释,使其更可读

re.search(pattern,string,flags = 0)

​根据模型去字符串中匹配指定的内容,匹配单个

re.findall(pattern,string,flags=0)

​匹配字符串中所有符合条件的元素

re.sub( pattern, repl, string, counts=0, flags=0)

​ 用于替换匹配的字符串,相比于str.replace功能更强大

re.split( pattern, string, maxsplit=0, flags=0)

​支持多字符切割,而str.split只支持单字符切割且不感知空格的数量

re.fullmatch(pattern,string,flags=0)

​整个字符串匹配成功就返回re object ,否则返回None

5.12.3 重要语法

re 的匹配语法

re.match 从头开始匹配

re.search 匹配包含

re.findall 把所有匹配到的字符放到以列表中,返回列表

re.split 以匹配到的字符当作列表分隔符

re.sub 匹配字符以替换

re.fullmatch 全部匹配

re.match (pattern,string,flages = 0)

​从起始位置开始根据模型去字符串中匹配指定的内容,匹配单个

pattern 正则表达式

string 要匹配的字符串

flags 标志位,用于控制正则表达式的匹配了方式

falgs标志位

re.I(re.IGNORECASE)忽略大小写(括号内是完整写法,下同)

M(MULTILINE):多行模式,改变'^'和'$'的行为

S(DOALL):改变 . 的行为,make the '.' special character match any character at all ,including a newline ;without this flag, '.' will match anthing except a newline.

x(re.VERBOSE) 给表达式写注释,使其更可读

re.search(pattern,string,flags = 0)

​根据模型去字符串中匹配指定的内容,匹配单个

re.findall(pattern,string,flags=0)

​匹配字符串中所有符合条件的元素

re.sub( pattern, repl, string, counts=0, flags=0)

​ 用于替换匹配的字符串,相比于str.replace功能更强大

re.split( pattern, string, maxsplit=0, flags=0)

​支持多字符切割,而str.split只支持单字符切割且不感知空格的数量

re.fullmatch(pattern,string,flags=0)

​整个字符串匹配成功就返回re object ,否则返回None

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值