zoukankan      html  css  js  c++  java
  • python学习之模块-模块(五)

    5.10 包

    5.10.1 包的概念

    【官网解释】
    Packages are a way of structuring Python’s module namespace by using “dotted module names”
    包是一种通过使用‘.模块名’来组织python模块名称空间的方式。

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

    【强调】:

    1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错
    2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包的本质就是一种模块

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

    1. 将该包内 __init__py文件加载到内存.
    2. 创建一个以该包 命名的名称空间.
    3. 通过 包名. 的方式引用__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 匹配字符串的结束,如果是换行,只匹配到换行前的结果
    匹配一个换行符
    匹配一个制表符
    ^ 匹配字符串的开始
    $ 匹配字符串的结尾
    . 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
    [...] 匹配字符组中的字符
    [^...] 匹配除了字符组中的字符的所有字符
    * 匹配0个或者多个左边的字符。
    + 匹配一个或者多个左边的字符。
    匹配0个或者1个左边的字符,非贪婪方式。
    {n} 精准匹配n个前面的表达式。
    {n,m} 匹配n到m次由前面的正则表达式定义的片段,贪婪方式
    a|b 匹配a或者b。
    () 匹配括号内的表达式,也表示一个组

    5.12.2 匹配模式

    import re
    #单个字符匹配
    print(re.findall('dd','12a34567890 alex *(_'))
    print(re.findall('w','太白jx 12*() _'))
    print(re.findall('d','1234567890 alex *(_'))
    print(re.findall('Ahel','hello 太白金星 -_- 666'))
    print(re.findall('
    ','hello 
     太白金星 	*-_-*	 
    666'))
    print(re.findall('.','da
    sdasda
    sdf231	2314!#!@#!@'))
    print(re.findall('hh$','dajqwdadnhhldsdoashhdosasdhh'))
    
    # 元字符匹配
    # . 匹配任意一个字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符
    print(re.findall('a.b','ab aacb a*b a2b a牛ab a
    b')) #以a开头,以b结尾中间必须有一个字符
    print(re.findall('a..b','ab aacb a*b a2b a牛ab a
    b',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

    仅供参考,欢迎指正
  • 相关阅读:
    海量数据框架变迁——阿里巴巴上市背后的技术力量
    redis集群配置
    【等待优化】sql server CXPACKET 等待 导致 CPU飙高、CPU100%
    (4.39)sql server如何配置分布式事务(MSDTC)
    mysql断电,mysql ibdata 文件损坏(批量利用mysql表空间导入导出)
    mysqlfrm使用
    (1.1)zabbix 基础概念及工作原理整理【转】
    (5.17)mysql集群技术概述(LVS、Keepalived、HAproxy)
    事务日志备份失败错误:Backup detected log corruption in database
    sql server事务日志解析工具(开源,类似apexsql log)
  • 原文地址:https://www.cnblogs.com/jjzz1234/p/11122948.html
Copyright © 2011-2022 走看看