模块与包,包与模块

作者: 编程应用  发布:2019-09-26

一、模块的利用

模块定义:一类别效用的会集体

分成三大类:1.自定义模块

      2.嵌入模块(譬喻 time,os,sys)

      3.其三方模块

模块的表现格局

  1.使用python编写的py文件

  2.已被编写翻译为分享库或DLL的C或C++增添

  3.把一两种模块组织到一道的文书夹(ps:文件夹下有贰个__init__.py文件,该文件夹称为包)

  4.选择C编写并链接到python解释器的放置模块

干什么要用模块:

  1.方可拿来放置、第三方的模块,然后直接行使,这种拿来就用的方法,会小幅度的晋级换代开垦效用

  2.将次第中国共产党用的一部分功力团体到三个文书中,然后程序各部分零件可以选择该公文中的功效。

    优点是 缩短代码冗余,加强程序的集体结构性与可维护性

怎么用模块:

  一个py文件就是一个模块,如果文件名叫modules.py,模块名则为modules

  ps:模块的利用必需搞精晓哪个人是实践文书,哪个人是被导入的模块

1.1 模块

1、模块的运用之import

图片 1图片 2

#:coding:utf-8#modules.pyprint('from the modules.py')money=1000def read1():    print('modules模块.read1',money)def read2():    print('modules模块.read2')    read1()def change():    global money    money=0

modules.py图片 3图片 4

import modules money=111111111111print(modules.money)print(modules.read1)print(modules.read2)print(modules.change)modules.money=2222print###结果为money=111111111111modules.read1()#modules模块.read1 2222   #这个更改成功modules.money=2222def read1():#此处定义read1    print('run.py中的read1')modules.read1()#执行结果仍为modules模块.read1 2222money=20000000modules.change()#此处执行了modules中change函数print###此处为上述money=20000000print(modules.money)##结果为0import modules as spam ##可以as 起个别名print(spam.money)  #依旧执行成功  结果为0

run.py

进行文书:run.py 被导入模块是:modules.py

第一次导入模块会发生三件事: 

  1、成立贰个模块modules.py的称号空间
  2、施行模块对应的文件modules.py,将发出的名字丢到模块的名目空间中
  3、在脚下施行文书的称谓空间中获得三个名字modules,该名字正是指向模块modules.py的名称空间的
  import modules# modules=modules.py名称空间的内存地址

ps

  在当下推行文书中引用模块中的名字语法为:modules.名字,必需抬高modules.作为前缀
  modules.名字约等于指名道姓地跟某二个称呼空间要名字,根本不会与日前实践文书的名字争执

1.1.1 模块介绍

相近的光景:多少个模块正是三个分包了一组功用的python文件,举个例子spam.py,模块名称叫spam,能够经过import spam使用。

在python中,模块的运用方式都以一致的,但实质上细说的话,模块可以分成多少个通用项目: 

1 使用python编写的.py文件

2 已被编译为分享库或DLL的C或C++增加

3 把一多种模块社团到一起的文书夹(注:文件夹下有三个__init__.py文件,该文件夹称之为包)

4 使用C编写并链接到python解释器的松开模块

 

2、模块的运用之 from import

图片 5图片 6

#modules.py# print('from the modules.py')__all__=['money','read1']money=1000def read1():    print('spam模块.read1',money)def read2():    print('spam模块.read2')    read1()def change():    global money    money=0

spam.py图片 7图片 8

from spam import money,read1,read2,change#def read1():    print('run.py.read1')read1()      #  run.py.read1read2()      #  spam模块.read2  ------------>   spam模块.read1 1000from spam import money as myprint   #1000# ===========================================from spam import * # * 会检索被导入模块中的__all__指定的名字,如果没有该变量那默认导入所有print  #1000print  # <function read1 at 0x0000000001EB1C80># print #会报错# print #会报错

run.py

进行文书:run.py 被导入模块: spam.py

第三回导入模块会发出三件事
  1、创制一个模块spam.py的称谓空间
  2、施行模块对应的文件spam.py,将生出的名字丢到模块的称号空间中
  3、在脚下实行文书的名称空间中拿到贰个名字money,该名字就是指向模块spam.py的名号空间的老大money
  from spam import money,read1,read2,change

二种导入方式的自查自纠
同样点:函数的成效域关系在概念阶段就规定死了,与调用地点毫不相关

from import
可取:可以绝不加前缀而直白援用名字,更轻便
症结:轻松与当前实施文书中的名字争持

import
亮点:指名道姓跟某三个名称空间要名字,明确不会与当前名称空间中的名字争辩
缺点:必需抬高前缀

1.1.2 为何要接纳模块

1、从文件品级协会程序,更方便管理

乘胜程序的进化,成效更是多,为了方便管理,大家平时将先后分成二个个的文件,那样做程序的构造更清晰,方便管理。这时我们不仅能够把这个文件作为脚本去推行,还足以把她们作为模块来导入到别的的模块中,实现了作用的重复使用

2、拿来主义,进步开拓效能

同一的准则,大家也足以下载外人写好的模块然后导入到自身的品种中应用,这种拿来主义,能够十分的大地提升大家的开销功能

#ps:

假诺您退出python解释器然后再也步向,那么你此前定义的函数可能变量都将遗失,由此我们平日将次第写到文件中以便永恒保存下去,供给时就因此python test.py方式去实施,此时test.py被喻为脚本script。

以spam.py为例来介绍模块的选用:文件名spam.py,模块名spam

#spam.py

print('from the spam.py')



money=1000



def read1():

    print('spam模块:',money)



def read2():

    print('spam模块')

    read1()



def change():

    global money

    money=0

 

模块使用.py

import spam



money=1

print(spam.money)



print(spam.read1)

print(spam.read2)

print(spam.change)

 

 

测试一

money=1

print(spam.money)

 

测量检验二(相对导入):

def read1():

    print('from current')

# spam.read1()

spam.read2()

 

测试三:

money=1

spam.change()

print(money)

spam.read1()

 

3、循环导入的主题材料

图片 9图片 10

# print## x='m1.py'## from m2 import y#print('正在导入m1')def f1():    from m2 import y,f2    print    f2()x='m1.py'

m1.py图片 11图片 12

# print## y='m2'## from m1.py import xprint('正在导入m2')def f2():    from m1 import x    printy='m2.py'

m2.py

###   run.py# 1、创建m1.py的名称空间# 2、执行m1.py的代码,将产生的名字丢到m1.py的名称空间中# 3、在当前执行文件的名称空间中拿到一个名字m1import m1m1.f1()

1.2 使用模块之import

4、模块的搜寻路线

模块搜索路线优先级:

  内部存款和储蓄器 --------> 内置的模块 --------> sys.path

图片 13图片 14

#模块的查找顺序1、在第一次导入某个模块时,会先检查该模块是否已经被加载到内存中(当前执行文件的名称空间对应的内存),如果有则直接引用    ps:python解释器在启动时会自动加载一些模块到内存中,可以使用sys.modules查看2、如果没有,解释器则会查找同名的内建模块3、如果还没有找到就从sys.path给出的目录列表中依次寻找spam.py文件。#sys.path的初始化的值来自于:The directory containing the input script (or the current directory when no file is specified).PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).The installation-dependent default.#需要特别注意的是:我们自定义的模块名不应该与系统内置模块重名。虽然每次都说,但是仍然会有人不停的犯错。 #在初始化后,python程序可以修改sys.path,路径放到前面的优先于标准库被加载。1 >>> import sys2 >>> sys.path.append('/a/b/c/d')3 >>> sys.path.insert(0,'/x/y/z') #排在前的目录,优先被搜索注意:搜索时按照sys.path中从左到右的顺序查找,位于前的优先被查找,sys.path中还可能包含.zip归档文件和.egg文件,python会把.zip归档文件当成一个目录去处理,#首先制作归档文件:zip module.zip foo.py bar.py import syssys.path.append('module.zip')import foo,bar#也可以使用zip中目录结构的具体位置sys.path.append('module.zip/lib/python')#windows下的路径不加r开头,会语法错误sys.path.insert(0,r'C:UsersAdministratorPycharmProjectsa') #至于.egg文件是由setuptools创建的包,这是按照第三方python库和扩展时使用的一种常见格式,.egg文件实际上只是添加了额外元数据(如版本号,依赖项等)的.zip文件。#需要强调的一点是:只能从.zip文件中导入.py,.pyc等文件。使用C编写的共享库和扩展块无法直接从.zip文件中加载(此时setuptools等打包系统有时能提供一种规避方法),且从.zip中加载文件不会创建.pyc或者.pyo文件,因此一定要事先创建他们,来避免加载模块是性能下降。

详尽的介绍

1.2.1 import的使用

模块能够分包可举办的话语和函数的概念,这一个话语的指标是伊始化模块,它们只在模块名第一次境遇导入import语句时才实行(import语句是足以在前后相继中的率性地方运用的,且针对同一个模块很import数十次,为了堤防你再次导入,python的优化花招是:第一回导入后就将模块名加载到内部存款和储蓄器了,后续的import语句仅是对曾经加载到内部存款和储蓄器中的模块对象扩展了一遍引用,不会再一次推行模块内的口舌),如下

#test.py

import spam #只在第一次导入时才执行spam.py内代码,此处的显式效果是只打印一次'from the spam.py',当然其他的顶级代码也都被执行了,只不过没有显示效果.

import spam

import spam

import spam

 

'''

推行结果:

from the spam.py

'''

ps:大家得以从sys.module中找到当前早就加载的模块,sys.module是贰个字典,内部含有模块名与模块对象的炫丽,该字典决定了导入模块时是或不是要求再一次导入。

 

5、区分python文件的三种用途

一个python文件有二种用途:
  1、能够试行运营:__name__ == '__main__'
  2、能够被看作模块导入:__name__ == '模块名'

if __name__ == '__main__':

1.2.2 在率先次导入模块时会做三件事,重复导入会直接援用内部存款和储蓄器中已经加载好的结果

1.为源文件(spam模块)创立新的名目空间,在spam中定义的函数和章程假若使用到了global时访谈的就是那个名称空间。

2.在新创立的命名空间中进行模块中蕴藏的代码,见初步导入import spam

 提醒:导入模块时终归实践了什么?

实则函数定义也是“被实践”的言语,模块品级函数定义的施行将函数名归入模块全局名称空间表,用globals()能够查阅

3.创建名字spam来援引该命名空间

    那么些名字和变量名没什么区别,都以‘第一类的’,且使用spam.名字的点子

    能够访问spam.py文件中定义的名字,spam.名字与test.py中的名字源于

    四个完全不一致的地方。

二、包的施用

1.2.3 被导入模块有单独的称呼空间

种种模块都以多个单独的称号空间,定义在这一个模块中的函数,把这么些模块的称呼空间作为全局名称空间,那样大家在编写自个儿的模块时,就不要忧虑我们定义在团结模块中全局变量会在被导入时,与使用者的全局变量龃龉

测试一:money与spam.money不冲突

#test.py

import spam

money=10

print(spam.money)

 

'''

实施结果:

from the spam.py

1000

'''

 

测试二:read1与spam.read1不冲突

#test.py

import spam

def read1():

    print('========')

spam.read1()

 

'''

实践结果:

from the spam.py

spam->read1->money 1000

'''

测量试验三:实行spam.change()操作的全局变量money依然是spam中的

#test.py

import spam

money=1

spam.change()

print(money)

 

'''

施行结果:

from the spam.py

1

'''

 

 

 

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.2.4 为模块名起别称

为曾经导入的模块起别称的点子对编写可扩张的代码很有用

import spam as sm

print(sm.money)



engine=input('>>: ')

if engine == 'mysql':

    import mysql as sql

elif engine == 'oracle':

    import oracle as sql



sql.parse()

 

有两中sql模块mysql和oracle,依照顾客的输入,选拔不相同的sql功效

一旦有多个模块xmlreader.py和csvreader.py,它们都定义了函数read_data(filename):用来从文件中读取一些多少,但使用分化的输入格式。能够编写制定代码来选用性地挑选读取模块

if file_format == 'xml':

    import xmlreader as reader

elif file_format == 'csv':

    import csvreader as reader

data=reader.read_date(filename)

 

 

2、为啥要用包

包的精神正是二个文书夹, 那么文件夹独一的效用就是将文件协会起来 随着功效越写越来越多 ,大家无法将就此功用都放置二个文书中, 于是大家选择模块去协会效劳, 而随着模块越来越多, 我们就须要用文件夹将模块文件协会起来,以此来提升程序的结构性和可维护性。

ps:注意事项

#1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如item.subitem.subsubitem,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。#2、import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件#3、包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间

|---示例|     ||---dir1 #文件夹|     |     |-----dir2 #文件夹|     |            |---p1 #包文件夹|     |               |||-------p2 #包文件夹|     |               |||       ||----- __init__.py|     |               |||       |------m3.py|     |               ||||     |               |||--- __init__.py|     |               ||----m1.py     |     |               |-----m2.py   |     ||     |------run.py  #执行文件

图片 15图片 16

#   run.pyfrom dir1.dir2 import p1p1.f1p1.f3()#======================================#dir1文件夹 ##dir2文件夹#======================================                          #p1下的文件内容#__init.pyfrom .m1 import f1from .m2 import f2from .p2.m3 import f3#------------------------------------------#m1.pydef f1():    print('m1.f1')#-------------------------------------------#m2.pydef f2():    print('m2.f2')#-------------------------------------------#p1包文件夹#=======================================                         #p2下的文件内容#__init__.py#空#--------------------------------------------#m3.pydef f3():    print('m3.f3')

文件内容

#import p1#1 创建p1的名称空间#2 执行p1下的__init__.py文件的代码,将执行过程中产生的名字都丢到名称空间中#3 在当前执行文件中拿到一个名字p1,p1指向__init__.py的名称空间

#包内模块的:绝对导入与相对导入#    绝对导入:每次导入都是以最顶级包为起始开始查找的#    相对导入:相对于当前所在的文件,.代表当前所在的文件,..代表上一级,...#        强调:#            相对导入只能在被导入的模块中使用#           在执行文件里不能用.或者..的导入方式#注意:# 但凡在导入时带点的,点的左边必须是一个包

1.2.5 在一行导入多少个模块

import sys,os,re

 

三、软件开辟的目录标准

  图片 17

1、bin 文件夹 :一般放程序运行文件

2、conf 文件夹:一些配置消息

3、core 文件夹:程序的基本文件 与客户挂钩的

4、db 文件夹 :数据文件所在地

5、lib 文件夹 :公共模块文件

6、log 文件夹 :日志文件所在地

7、Readme 文件 :程序的提携文书档案

1.2.6 使用模块之from ... import...

四、logging模块

1.2.6.1  from ... import... .的使用

from spam import money,read1,read2,change



money=1

print(money)



read1='read1'

print(read1)



money=1

read1()



def read1():

    print('from current func')



read2()



money=1

change()

print(money)

 

 

一、日志的等第

CRITICAL = 50 #FATAL = CRITICALERROR = 40WARNING = 30 #WARN = WARNINGINFO = 20DEBUG = 10NOTSET = 0 #不设置

1.2.7 from...import 与import的对比

独一的差距就是:使用from...import...则是将spam中的名字直接导入到当前的名称空间中,所以在当前名称空间中,直接利用名字就足以了、无需加前缀:spam.

#from...import...的办法有好处也可能有缺陷

    好处:使用起来方便了

    坏处:轻松与方今实施文书中的名字顶牛

 

read1=1

print(money,read1,read2,change)



print(_money)

print(read1,read2,change)



from spam import _money

print(_money)



import spam

spam.read1()



import sys

print(sys.path)



sys.path.append(r'D:videopython20期day51_模块aaa')

import spam

print(spam.money)





import spam,time

time.sleep(10)

import spam

print(spam.money)



import sys,spam

print('spam' in  sys.modules)

print('time' in sys.modules)



import time

print(time)

time.sleep(3)

 

 

二、私下认可等级为warning ,暗中认可打字与印刷到极点

import logginglogging.debug('调试debug')logging.info('消息info')logging.warning('警告warn')logging.error('错误error')logging.critical('严重critical')'''WARNING:root:警告warnERROR:root:错误errorCRITICAL:root:严重critical'''

1.2.8 from spam import *

#from spam import * 把spam中颇具的不是以下划线(_)初始的名字都导入到当前地点

#绝大许多处境下大家的python程序不应该使用这种导入格局,因为*你不领悟你导入什么名字,很有望会覆盖掉你前边已经定义的名字。并且可读性非常的差,在交互式景况中程导弹入时从没难点。

 

三、为logging 模块内定全局配置,针对全部logger有效,调控打字与印刷到文件

可在logging.basicConfig()函数中通过具体参数来更改logging模块默认行为,可用参数有

图片 18图片 19

filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。format:指定handler使用的日志显示格式。 datefmt:指定日期时间格式。 level:设置rootlogger 的日志级别 stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。#格式%s:Logger的名字,并非用户名,详细查看%s:数字形式的日志级别%(levelname)s:文本形式的日志级别%s:调用日志输出函数的模块的完整路径名,可能没有%s:调用日志输出函数的模块的文件名%s:调用日志输出函数的模块名%s:调用日志输出函数的函数名%d:调用日志输出函数的语句所在的代码行%f:当前时间,用UNIX标准的表示时间的浮 点数表示%(relativeCreated)d:输出日志信息时的,自Logger创建以 来的毫秒数%s:字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒%d:线程ID。可能没有%(threadName)s:线程名。可能没有%d:进程ID。可能没有%s:用户输出的消息  

logging.basicConfig()图片 20图片 21

#========使用import logginglogging.basicConfig(filename='access.log',                    format='%s - %s - %(levelname)s -%s:  %s',                    datefmt='%Y-%m-%d %H:%M:%S %p',                    level=10)logging.debug('调试debug')logging.info('消息info')logging.warning('警告warn')logging.error('错误error')logging.critical('严重critical')#========结果access.log内容:2017-07-28 20:32:17 PM - root - DEBUG -test:  调试debug2017-07-28 20:32:17 PM - root - INFO -test:  消息info2017-07-28 20:32:17 PM - root - WARNING -test:  警告warn2017-07-28 20:32:17 PM - root - ERROR -test:  错误error2017-07-28 20:32:17 PM - root - CRITICAL -test:  严重criticalpart2: 可以为logging模块指定模块级的配置,即所有logger的配置

固化套路

1.3 py文件分别三种用途:模块与剧本

写好的二个python文件能够有三种用途:

    一:脚本,二个文书就是漫天程序,用来被施行

    二:模块,文件中存放着一群效果,用来被导入使用

 

#python为大家放手了全局变量__name__,

    当文件被用作脚本试行时:__name__ 等于'__main__'

    当文件被当作模块导入时:__name__等于模块名

 

#功效:用来调整.py文件在分歧的运用场景下进行不一致的逻辑

    if __name__ == '__main__':

 

四、logging模块的Formatter ,Handler,Logger,Filte 对象

#logger:产生日志的对象#Filter:过滤日志的对象#Handler:接收日志然后控制打印到不同的地方,FileHandler用来打印到文件中,StreamHandler用来打印到终端#Formatter对象:可以定制不同的日志格式对象,然后绑定给不同的Handler对象使用,以此来控制不同的Handler的日志格式

图片 22图片 23

'''critical=50error =40warning =30info = 20debug =10'''import logging#1、logger对象:负责产生日志,然后交给Filter过滤,然后交给不同的Handler输出logger=logging.getLogger(__file__)#日志名#2、Filter对象:不常用,略#3、Handler对象:接收logger传来的日志,然后控制输出h1=logging.FileHandler('t1.log') #打印到文件h2=logging.FileHandler('t2.log') #打印到文件h3=logging.StreamHandler() #打印到终端#4、Formatter对象:日志格式formmater1=logging.Formatter('%s - %s - %(levelname)s -%s:  %s',                    datefmt='%Y-%m-%d %H:%M:%S %p',)formmater2=logging.Formatter('%s :  %s',                    datefmt='%Y-%m-%d %H:%M:%S %p',)formmater3=logging.Formatter('%s %s',)#5、为Handler对象绑定格式h1.setFormatter(formmater1)h2.setFormatter(formmater2)h3.setFormatter(formmater3)#6、将Handler添加给logger并设置日志级别logger.addHandlerlogger.addHandlerlogger.addHandlerlogger.setLevel(10)#7、测试logger.debug('debug')logger.info('info')logger.warning('warning')logger.error('error')logger.critical('critical')

logging模块的一向套路

详尽步骤:

1、配图

图片 24

1、logger对象承担产出生之日志

logger1=logging.getLogger('xx日志')

2、filter过滤

3、handler对象须求与logger对象绑定,用来接受logger对象传过来的日记,决定打字与印刷到不一致的地点

fh1=logging.FileHandler(filename='a1.log',encoding='utf-8')fh2=logging.FileHandler(filename='a2.log',encoding='utf-8')sh=logging.StreamHandler()# 往终端打印的

4、formmater对象供给与handler对象绑定,用来调整handler对象的日志格式

图片 25图片 26

formmater1=logging.Formatter(    fmt='%s - %s - %(levelname)s -%s:  %s',    datefmt='%Y-%m-%d %H:%M:%S %p')#两种不同的日志格式formmater2=logging.Formatter(    fmt='%s - %(levelname)s :  %s',    datefmt='%Y-%m-%d %H:%M:%S %p')

formmater格式

ps1:设置日志品级:logger与handler两层关卡都放行,日志最终才放行

logger1.setLevel  #logger对象设置fh1.setLevel(10)  #文件1的handler设置级别fh2.setLevel  #文件2的handler设置级别sh.setLevel   #打印到终端的handler设置级别

ps2:创设logger对象与handler对象的绑定关系

logger1.addHandlerlogger1.addHandlerlogger1.addHandler

ps3:创建handler对象与formmater对象的绑定关系

fh1.setFormatter(formmater1)fh2.setFormatter(formmater1)sh.setFormatter(formmater2)

末段:使用logger1对象产出生之日志,打印到分裂的岗位

logger1.debug('蘑菇买彩票中奖30元')logger1.warning('蘑菇花了1000元买彩票')

1.4 模块寻觅路线

模块的寻觅顺序是:内部存款和储蓄器中已经加载的模块->内置模块->sys.path路线中包含的模块

模块的追寻顺序

1、在率先次导入有些模块时(比方spam),会先反省该模块是不是早就被加载到内部存款和储蓄器中(当前进行文书的名目空间对应的内部存储器),固然有则平素援用

    ps:python解释器在运营时会自行加载一些模块到内部存款和储蓄器中,能够动用sys.modules查看

2、若无,解释器则会招来同名的内建立模型块

3、即使还尚未找到就从sys.path给出的目录列表中逐条搜索spam.py文件。

 

五、Logger与Handler的级别

logger与handler两层关卡都放行,日志最后才放行

在意:logger是首先层关卡 ,然后才到handler

图片 27图片 28

import loggingform=logging.Formatter('%s - %s - %(levelname)s -%s:  %s',                    datefmt='%Y-%m-%d %H:%M:%S %p',)ch=logging.StreamHandler()ch.setFormatter# ch.setLevelch.setLevel(20)l1=logging.getLogger('root')# l1.setLevell1.setLevel(10)l1.addHandlerl1.debug('l1 debug')

示例

1.5 包

六、具人体模型块的运用方法

假诺每趟使用模块都得依据上述的步调,这就太繁琐了。

据此logging模块有一个从字典中加载配置的艺术

1.5.1 什么是包

包正是二个满含有__init__.py文件的文件夹,所以其实我们创立包的目标就是为了用文件夹将文件/模块组织起来

内需重申的是:

  1. 在python3中,即便包下未有__init__.py文件,import 包依然不会报错,而在python2中,包下应当要有该文件,不然import 包报错

 

  2. 开立包的指标不是为了运营,而是被导入使用,记住,包只是模块的一种样式而已,包的真面目正是一种模块

1.应用模板

图片 29图片 30

"""logging配置"""import osimport logging.config# 定义三种日志输出格式 开始standard_format = '[%s][%(threadName)s:%d][task_id:%s][%s:%d]'                   '[%(levelname)s][%s]' #其中name为getlogger指定的名字simple_format = '[%(levelname)s][%s][%s:%d]%s'id_simple_format = '[%(levelname)s][%s] %s'# 定义日志输出格式 结束logfile_dir = os.path.dirname(os.path.abspath(__file__))  # log文件的目录logfile_name = 'all2.log'  # log文件名# 如果不存在定义的日志目录就创建一个if not os.path.isdir(logfile_dir):    os.mkdir(logfile_dir)# log文件的全路径logfile_path = os.path.join(logfile_dir, logfile_name)# log配置字典LOGGING_DIC = {    'version': 1,    'disable_existing_loggers': False,    'formatters': {        'standard': {            'format': standard_format        },        'simple': {            'format': simple_format        },    },    'filters': {},    'handlers': {        #打印到终端的日志        'console': {            'level': 'DEBUG',            'class': 'logging.StreamHandler',  # 打印到屏幕            'formatter': 'simple'        },        #打印到文件的日志,收集info及以上的日志        'default': {            'level': 'DEBUG',            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件            'formatter': 'standard',            'filename': logfile_path,  # 日志文件            'maxBytes': 1024*1024*5,  # 日志大小 5M            'backupCount': 5,            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了        },    },    'loggers': {        #logging.getLogger拿到的logger配置        '': {            'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕            'level': 'DEBUG',            'propagate': True,  # 向上(更高level的logger)传递        },    },}def load_my_logging_cfg():    logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置    logger = logging.getLogger(__name__)  # 生成一个log实例    logger.info('It works!')  # 记录该文件的运行状态if __name__ == '__main__':    load_my_logging_cfg()logging配置文件

logging配置模板图片 31图片 32

"""MyLogging Test"""import timeimport loggingimport my_logging  # 导入自定义的logging配置logger = logging.getLogger(__name__)  # 生成logger实例def demo():    logger.debug("start range... time:{}".format(time.time    logger.info("中文测试开始。。。")    for i in range(10):        logger.debug("i:{}".format        time.sleep(0.2)    else:        logger.debug("over range... time:{}".format(time.time    logger.info("中文测试结束。。。")if __name__ == "__main__":    my_logging.load_my_logging_cfg()  # 在你程序文件的入口加载自定义logging配置    demo()

使用图片 33图片 34

#1、有了上述方式我们的好处是:所有与logging模块有关的配置都写到字典中就可以了,更加清晰,方便管理#2、我们需要解决的问题是:    1、从字典加载配置:logging.config.dictConfig(settings.LOGGING_DIC)    2、拿到logger对象来产生日志    logger对象都是配置到字典的loggers 键对应的子字典中的    按照我们对logging模块的理解,要想获取某个东西都是通过名字,也就是key来获取的    于是我们要获取不同的logger对象就是    logger=logging.getLogger('loggers子字典的key名')        但问题是:如果我们想要不同logger名的logger对象都共用一段配置,那么肯定不能在loggers子字典中定义n个key    'loggers': {            'l1': {            'handlers': ['default', 'console'],  #            'level': 'DEBUG',            'propagate': True,  # 向上(更高level的logger)传递        },        'l2: {            'handlers': ['default', 'console' ],             'level': 'DEBUG',            'propagate': False,  # 向上(更高level的logger)传递        },        'l3': {            'handlers': ['default', 'console'],  #            'level': 'DEBUG',            'propagate': True,  # 向上(更高level的logger)传递        },}    #我们的解决方式是,定义一个空的key    'loggers': {        '': {            'handlers': ['default', 'console'],             'level': 'DEBUG',            'propagate': True,         },}这样我们再取logger对象时logging.getLogger(__name__),不同的文件__name__不同,这保证了打印日志时标识信息不同,但是拿着该名字去loggers里找key名时却发现找不到,于是默认使用key=''的配置

log配置字典相关难点

1.5.2 为啥要利用包

包的真面目正是三个文书夹,那么文件夹独一的效力正是将文件协会起来

乘势成效越写越多,大家不可能将为此成效都置于一个文书中,于是大家采纳模块去组织成效,而随着模块越来越多,大家就要求用文件夹将模块文件组织起来,以此来升高程序的结构性和可维护性

注意事项:

#1.关于包相关的导入语句也分为import和from ... import ...三种,然而无论是哪一类,无论在怎么样职位,在导入时都无法不依据三个准则:凡是在导入时带点的,点的左侧都必需是叁个包,不然违法。能够包括再而三串的点,如item.subitem.subsubitem,但都必得遵照这几个条件。但对于导入后,在应用时就向来不这种范围了,点的侧面能够是包,模块,函数,类(它们都得以用点的主意调用自身的性质)。

#2、import导入文本时,发生名称空间中的名字源于文件,import 包,产生的名号空间的名字千篇一律来自文件,即包下的__init__.py,导入包本质正是在导入该文件

#3、包A和包B下有同超模块也不会争辨,如A.a与B.a来自俩个命名空间

2.示例

|----示例|    |---bin|    |    |----start.py  #启动文件|    ||    |---conf|    |    |----settings.py   #配置文件(logging配置)|    ||    |---core|    |    |----  src.py   #业务核心逻辑|    ||    |---lib|    |    |---- common.py    #公共库|    ||    |---  log    #日志

图片 35图片 36

import osBASE_DIR=os.path.dirname(os.path.dirname(__file__))standard_format = '[%s][%(threadName)s:%d][task_id:%s][%s:%d]'                   '[%(levelname)s][%s]' #其中name为getlogger指定的名字simple_format = '[%(levelname)s][%s][%s:%d]%s'id_simple_format = '[%(levelname)s][%s] %s'# log文件的全路径fh1_logfile_path = r'%s%s%s' %(BASE_DIR,'log','b1.log')fh2_logfile_path = r'%s%s%s' %(BASE_DIR,'log','b2.log')# log配置字典LOGGING_DIC = {    'version': 1,    'disable_existing_loggers': False,    'formatters': {        'standard': {            'format': standard_format        },        'simple': {            'format': simple_format        },    },    'filters': {},    'handlers': {        #打印到终端的日志,使用的格式为 simple_format        'ch': {            'level': 'DEBUG',            'class': 'logging.StreamHandler',  # 打印到屏幕            'formatter': 'simple'        },        #打印到文件b1.log的日志,使用的格式为 standard_format        'fh1': {            'level': 'DEBUG',            'class': 'logging.FileHandler',  # 保存到文件            'formatter': 'standard',            'filename': fh1_logfile_path,  # 日志文件            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了        },        #打印到文件b2.log的日志,使用的格式为 standard_format        'fh2': {            'level': 'DEBUG',            'class': 'logging.FileHandler',  # 保存到文件            'formatter': 'standard',            'filename': fh2_logfile_path,  # 日志文件            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了        },    },    'loggers': {        '': {            'handlers': ['ch', 'fh1','fh2'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕            'level': 'DEBUG',            'propagate': False,        },    },}

settings配置图片 37图片 38

from conf import settingsimport logging.configdef get_logger:    logging.config.dictConfig(settings.LOGGING_DIC)    logger1=logging.getLogger    return logger1

common.py图片 39图片 40

from lib import commonlogger1=common.get_logger("交易日志")def shopping():    print('购物')def pay():    print('支付')    logger1.info('蘑菇 支付了1元')def transfer():    print('转账')    logger1.info('蘑菇给小火柴支付了200元')def withdraw():    print('提现')    logger1.info('蘑菇提现200元')func_dic={    '1': shopping,    '2': pay,    '3': transfer,    '4': withdraw}def run():    while True:        print("""        0 退出        1 购物        2 支付        3 转账        4 提现        """)        choice=input('请输入您的操作: ').strip()        if choice == '0':break        if choice not in func_dic:            print("输入的指令不存在,请重新输入")            continue        func_dic[choice]()

src.py图片 41图片 42

import sysimport osBASE_DIR=os.path.dirname(os.path.dirname(__file__))sys.path.appendfrom core import srcif __name__ == '__main__':    src.run()

start.py

1.5.3 包的施用之import

创建包package1,在package1创建package2

在包package第11中学开创文件init.py

# print('__init__.py')



x=1

# m1='m1'

# import m1 #错误

from package1 import m1

 

 

# package2='package2'

# import package2 #错误,单独导入包名称时不会导入包中所有包含的所有子模块

from package1 import package2

 

在包package第11中学开创文件m1.py

def f1():

    print('from f1 func')

 

在包package第22中学开创文件m2.py

def f2():
    print('f2')

 

亟需留意的是from后import导入的模块,必需是显著的多个不能带点,不然会有语法错误,如:from a import b.c是荒唐语法

五、re 模块

1.6 相对导入和相对导入

大家的最一级包glance是写给外人用的,然后在glance包内部也许有互相之间相互导入的急需,那时候就有相对导入和绝对导入两种方法:

纯属导入:以glance作为开局

相持导入:用.或许..的点子最佳初始(只可以在叁个包中使用,不可能用来分歧目录内)

一、什么是正则

正则正是用一些具体特殊意义的符号组合到一块来说述字符或字符串的法子。也许说正则正是用来描述一类东西的准绳。python中,它内嵌在python中,并经过re模块完毕。

正则表达式被编写翻译成一名目好些个的字节码,然后由C编写的异常引擎实行。

生存中到处是正则:

  举例我们陈说:4条腿

    就能够想到四条腿的动物恐怕桌子,椅子

  再描述:四条腿,活的

    就只有四条腿的动物那类

1.6.1 相对导入

包的选拔.py

# import package1

#

# # package1.f1()

# package1.f2()



import sys

sys.path.append(r'D:videopython20期day52_包测试三(相对导入)aaa')



import package1

package1.f2()

m1.py

def f1():

    print('from f1 func')

 

 

包1_init_.py

from .m1 import f1

from .package2.m2 import f2

 

m2.py

from ..m1 import f1

def f2():

    f1()

    print('f2')

 

二、常用相称情势

图片 43

#==========================re模块  正则表达式=============================import re#1、 w匹配数字字母下划线print(re.findall('w','hello 123 - _ *()'))#['h', 'e', 'l', 'l', 'o', '1', '2', '3', '_']print(re.findall('mogu','hello mogu, mogu say hello'))#前面mogu代表完全匹配#['mogu', 'mogu']#2、 W 上方的取反print(re.findall('W','hello 123 - _ *()'))#[' ', ' ', '-', ' ', ' ', '*', '']#3、 s 匹配任意空白字符print(re.findall('s','666 t jiayou'))#[' ', 't', ' ']#    S 上方取反#4、 d 匹配任意数字   D 取反匹配任意数字print(re.findall('d','666 t jianyou'))#['6', '6', '6']#5、 n 只匹配换行符, t 只匹配制表符print(re.findall('n','666 t jianyou'))print(re.findall('t','666 t jianyou'))#['n']#['t']#6、 ^ 匹配字符串的开头   $ 匹配字符串的结尾print(re.findall('^mogu','hello mogu, mogu say hello'))print(re.findall('mogu$','hello mogu, mogu say hello mogu'))# ^结果为空 只匹配开头# $ ['mogu']  只匹配匹配末尾#7、 . :点 代表匹配除了换行符以外的任意单个字符print(re.findall('a.c','a-c a*c a2c anc aacacacacac a c atc',re.DOTALL))# ['a-c', 'a*c', 'a2c', 'aac', 'a c', 'atc']# re.DOTALL  可以让换行符也匹配出来#8、 [] : 代表匹配指定范围的任意字符print(re.findall('d[-+*/]d','1+2 3!3 qweasd 2+3 1/2 2-3 axcz hello'))#['1+2', '2+3', '1/2', '2-3']print(re.findall('a[0-9]c','a1c aAc a2c acc axc a23c a*c a9c'))#['a1c', 'a2c', 'a9c']print(re.findall('a[0-9][0-9]c','a1c aAc a2c acc axc a23c a*c a9c'))#['a23c']print(re.findall('a[a-z]c','a1c aAc a2c acc axc a23c a*c a9c'))#['acc', 'axc']print(re.findall('a[A-Z]c','a1c aAc a2c acc axc a23c a*c a9c'))#['aAc']#9、重复匹配#9.1  ? : 代表左边那一个字符出现0次或者1次 可以用{0,1}print(re.findall('ab?','b ab abb bbabbabbabba'))#['ab', 'ab', 'ab', 'ab', 'ab', 'a']#9.2  * :代表左边那一个字符出现0次或者无穷次,如果没有可以凑合,但如果>1个,有多少就必须拿多少#   可以用{0,}print(re.findall('ab*','b ab abb bbabbababba'))#['ab', 'abb', 'abb', 'ab', 'abb', 'a']#9.3  + :代表左边那一个字符出现1次或者无穷次,至少要有一个,但如果有>1个,有多少就必须拿多少#   可以用{1,}print(re.findall('ab+','b ab abb bbabbabbabba'))#['ab', 'abb', 'abb', 'abb', 'abb']#9.4 {n,m}:代表左边那一个字符出现n次到m次,至少要有n个,但如果有>n个,就拿<=m个print(re.findall('ab{2,5}','b ab abb bbabbabbabba abbbbbbbb'))#['abb', 'abb', 'abb', 'abb', 'abbbbb']#9.5  .* : 匹配0个或无穷个任意字符,默认是贪婪匹配print(re.findall('a.*c','a123c hello ab123  c321 mogu c'))# ['a123c hello ab123  c321 mogu c'] 找离a最远的c#9.6  .*? : 匹配0个或无穷个任意字符,非贪婪匹配print(re.findall('a.*?c','a123c hello ab123  c321 mogu c'))#['a123c', 'ab123  c']  找离a最近的c#示例: 正则使用非贪婪匹配 ()括号的意思是  只取分组内的内容print(re.findall('href=""',''    '<div ><a href="https://www.baidu.com">点我啊</a>'    '</div><div ><a href="https://www.python.org">点我啊</a></div>'))

图片 44图片 45

#[]print(re.findall('a[1*-]b','a1b a*b a-b')) #[]内的都为普通字符了,且如果-没有被转意的话,应该放到[]的开头或结尾print(re.findall('a[^1*-]b','a1b a*b a-b a=b')) #[]内的^代表的意思是取反,所以结果为['a=b']print(re.findall('a[0-9]b','a1b a*b a-b a=b')) #[]内的^代表的意思是取反,所以结果为['a=b']print(re.findall('a[a-z]b','a1b a*b a-b a=b aeb')) #[]内的^代表的意思是取反,所以结果为['a=b']print(re.findall('a[a-zA-Z]b','a1b a*b a-b a=b aeb aEb')) #[]内的^代表的意思是取反,所以结果为['a=b']## print(re.findall('a\c','ac')) #对于正则来说a\c确实可以匹配到ac,但是在python解释器读取a\c时,会发生转义,然后交给re去执行,所以抛出异常print(re.findall(r'a\c','ac')) #r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义print(re.findall('a\\c','ac')) #同上面的意思一样,和上面的结果一样都是['a\c']#():分组print(re.findall('ab+','ababab123')) #['ab', 'ab', 'ab']print(re.findall('+123','ababab123')) #['ab'],匹配到末尾的ab123中的abprint(re.findall('+123','ababab123')) #findall的结果不是匹配的全部内容,而是组内的内容,?:可以让结果为匹配的全部内容print(re.findall('href=""','<a href="http://www.baidu.com">点击</a>'))#['http://www.baidu.com']print(re.findall('href=""','<a href="http://www.baidu.com">点击</a>'))#['href="http://www.baidu.com"']#|print(re.findall('compan','Too many companies have gone bankrupt, and the next one is my company'))

补充图片 46图片 47

import re#1 findallprint(re.findall('e','mogu like read') )   #['e', 'e'],findall返回所有满足匹配条件的结果,放在列表里#2 searchprint(re.search('e','mogu like read').group# e,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。#3 matchprint(re.match('e','mogu like read'))    #None,同search,不过在字符串开始处进行匹配,完全可以用search+^代替match#4 splitprint(re.split('[ ]','mogu like read'))     #['mogu', 'like', 'read'],先按'空格'分割得到'mogu' 'like' 'read'#5print('===>',re.sub('m','M','mogu like read movie')) #===> Mogu like read Movie,不指定n,默认替换所有print('===>',re.sub('m','M','mogu like read movie',1)) #===> Mogu like read movieprint('===>',re.sub('m','M','mogu like read movie',2)) #===> Mogu like read Movieprint('===>',re.sub('^$',r'52341','mogu like read movie')) #===> read like moguprint('===>',re.subn('m','M','mogu like read movie')) #===> ('Mogu like read Movie', 2),结果带有总共替换的个数#6obj=re.compile('d{2}')  #封装一种正则匹配模式print(obj.search('abc123eeee').group #12print(obj.findall('abc123eeee')) #['12'],重用了obj#=======================================print(re.findall(r'-?d+.?d*',"1-12*(60+-")) #找出所有数字['1', '-12', '60', '-40.35', '5', '-4', '3']#使用|,先匹配的先生效,|左边是匹配小数,而findall最终结果是查看分组,所有即使匹配成功小数也不会存入结果#而不是小数时,就去匹配,匹配到的自然就是,非小数的数,在此处即整数print(re.findall(r"-?d+.d*|","1-2*(60+-")) #找出所有整数['1', '-2', '60', '', '5', '-4', '3']

re模块的办法图片 48图片 49

#为何同样的表达式search与findall却有不同结果:print(re.search('(([+-*/]*d+.?d*)+)',"1-12*(60+-").group #print(re.findall('(([+-*/]*d+.?d*)+)',"1-12*(60+-")) #['/5', '*3']#看这个例子:+相当于...,是一系列分组print(re.search('+','123').group #group的作用是将所有组拼接到一起显示出来print(re.findall('+','123')) #findall结果是组内的结果,且是最后一个组的结果

findall与search

总括:尽量简洁,详细的如下

全心全意选择泛相配方式.*

尽恐怕利用非贪婪方式:.*?

选拔括号获得相配指标:用group去获得结果

有换行符就用re.S:修改格局

在线测量试验 :正则测验

1.6.2 相对导入

包的采纳.py

import package1



package1.f1()

package1.f2()



# import sys

#

# # sys.path.append(r'D:videopython20期day52_包测试二(绝对导入)package1package2')

# # sys.path.append(r'D:videopython20期day52_包测试二(绝对导入)package1')

#

 

m1.py

def f1():
    print('from f1 func')

包1_init_.py

from package1.m1 import f1

from package1.package2.m2 import f2

m2.py

def f2():

    print('f2')

 

包2_init_.py

from package1.package2 import m2

 

六、time与datetime模块

在Python中,日常有这两种艺术来表示时间:

  • 光阴戳(timestamp):平常来讲,时间戳表示的是从1970年11月1日00:00:00初阶按秒总计的偏移量。我们运转“type(time.time”,再次来到的是float类型。
  • 格式化的岁月字符串(Format String)
  • 结构化的时间(struct_time):struct_time元组共有9个成分共柒个因素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)
import time
#--------------------------当前时间为准,三种形式的时间print(time.time # 时间戳:1536155758.0554852print(time.strftime("%Y-%m-%d %X")) #格式化的时间字符串:'2018-09-05 21:55:58'print(time.localtime #本地时区的struct_timeprint(time.gmtime    #UTC时区的struct_time

图片 50图片 51

%a    Locale’s abbreviated weekday name.     %A    Locale’s full weekday name.     %b    Locale’s abbreviated month name.     %B    Locale’s full month name.     %c    Locale’s appropriate date and time representation.     %d    Day of the month as a decimal number [01,31].     %H    Hour (24-hour clock) as a decimal number [00,23].     %I    Hour (12-hour clock) as a decimal number [01,12].     %j    Day of the year as a decimal number [001,366].     %m    Month as a decimal number [01,12].     %M    Minute as a decimal number [00,59].     %p    Locale’s equivalent of either AM or PM.    (1)%S    Second as a decimal number [00,61].    (2)%U    Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0.    (3)%w    Weekday as a decimal number [0,6].     %W    Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0.    (3)%x    Locale’s appropriate date representation.     %X    Locale’s appropriate time representation.     %y    Year without century as a decimal number [00,99].     %Y    Year with century as a decimal number.     %z    Time zone offset indicating a positive or negative time difference from UTC/GMT of the form +HHMM or -HHMM, where H represents decimal hour digits and M represents decimal minute digits [-23:59, +23:59].     %Z    Time zone name (no characters if no time zone exists).     %%    A literal '%' character.

格式化字符串的年月格式

内部Computer认识的时间只可以是'时间戳'格式,而程序员可处理的可能说人类能看懂的时日有: '格式化的时日字符串','结构化的时日'

图片 52

import time#--------------------------按图1转换时间 # localtime # 将一个时间戳转换为当前时区的struct_time。secs参数未提供,则以当前时间为准。time.localtime()time.localtime(1473525444.037215)# gmtime 和localtime()方法类似,gmtime()方法是将一个时间戳转换为UTC时区的struct_time。# mktime : 将一个struct_time转化为时间戳。print(time.mktime(time.localtime#1536156163.0# strftime(format[, t]) : 把一个代表时间的元组或者struct_time(如由time.localtime()和# time.gmtime转化为格式化的时间字符串。如果t未指定,将传入time.localtime()。如果元组中任何一个# 元素越界,ValueError的错误将会被抛出。print(time.strftime("%Y-%m-%d %X", time.localtime#2018-09-05 22:02:43# time.strptime(string[, format])# 把一个格式化时间字符串转化为struct_time。实际上它和strftime()是逆操作。print(time.strptime('2011-05-05 16:37:06', '%Y-%m-%d %X'))# time.struct_time(tm_year=2011, tm_mon=5, tm_mday=5, tm_hour=16, tm_min=37, tm_sec=6, tm_wday=3, tm_yday=125, tm_isdst=-1)#在这个函数中,format默认为:"%a %b %d %H:%M:%S %Y"。

图片 53

import time#--------------------------按图2转换时间# asctime : 把一个表示时间的元组或者struct_time表示为这种形式:'Sun Jun 20 23:21:05 1993'。# 如果没有参数,将会将time.localtime()作为参数传入。print(time.asctime#Wed Sep  5 22:06:41 2018# ctime : 把一个时间戳转化为time.asctime()的形式。如果参数未给或者为# None的时候,将会默认time.time()为参数。它的作用相当于time.asctime(time.localtime。print(time.ctime  # Wed Sep  5 22:06:41 2018print(time.ctime(time.time  # Wed Sep  5 22:06:41 2018

图片 54图片 55

#时间加减import datetime,timeprint(datetime.datetime.now #返回 2018-09-05 22:08:48.246537print(datetime.date.fromtimestamp(time.time  # 时间戳直接转成日期格式 2018-09-05# print(datetime.datetime.now() + datetime.timedelta #当前时间+3天print(datetime.datetime.now() + datetime.timedelta #当前时间-3天print(datetime.datetime.now() + datetime.timedelta #当前时间+3小时print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分#c_time  = datetime.datetime.now()print(c_time.replace(minute=3,hour=2)) #时间替换

datetime模块!!!

1.7 软件开拓标准

 图片 56

 

图1-1  

 

#===============>star.py

import sys,os

BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

sys.path.append(BASE_DIR)



from core import src



if __name__ == '__main__':

    src.run()

 

#===============>settings.py

import os



BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

DB_PATH=os.path.join(BASE_DIR,'db','db.json')

LOG_PATH=os.path.join(BASE_DIR,'log','access.log')

LOGIN_TIMEOUT=5

 

"""

logging配置

"""

# 定义两种日志输出格式

standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' 

                  '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字

simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'

id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'

 

# log配置字典

LOGGING_DIC = {

    'version': 1,

    'disable_existing_loggers': False,

    'formatters': {

        'standard': {

            'format': standard_format

        },

        'simple': {

            'format': simple_format

        },

    },

    'filters': {},

    'handlers': {

 

        #打字与印刷到极点的日记

 'console': {

            'level': 'DEBUG',

            'class': 'logging.StreamHandler',  # 打印到屏幕

            'formatter': 'simple'

        },

 

        #打字与印刷到文件的日志,收罗info及以上的日记

       

 'default': {

            'level': 'DEBUG',

            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件

            'formatter': 'standard',

            'filename': LOG_PATH,  # 日志文件

            'maxBytes': 1024*1024*5,  # 日志大小 5M

            'backupCount': 5,

            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了

        },

    },

    'loggers': {

 

        #logging.getLogger(__name__)拿到的logger配置

      

  '': {

            'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕

            'level': 'DEBUG',

            'propagate': True,  # 向上(更高level的logger)传递

        },

    },

}

 

 

#===============>src.py

from conf import settings

from lib import common

import time



logger=common.get_logger(__name__)



current_user={'user':None,'login_time':None,'timeout':int(settings.LOGIN_TIMEOUT)}

def auth(func):

    def wrapper(*args,**kwargs):

        if current_user['user']:

            interval=time.time()-current_user['login_time']

            if interval < current_user['timeout']:

                return func(*args,**kwargs)

        name = input('name>>: ')

        password = input('password>>: ')

        db=common.conn_db()

        if db.get(name):

            if password == db.get(name).get('password'):

                logger.info('登录成功')

                current_user['user']=name

                current_user['login_time']=time.time()

                return func(*args,**kwargs)

        else:

            logger.error('用户名不存在')



    return wrapper



@auth

def buy():

    print('buy...')



@auth

def run():



    print('''

    1 购物

    2 查看余额

    3 转账

    ''')

    while True:

        choice = input('>>: ').strip()

        if not choice:continue

        if choice == '1':

            buy()

 

#===============>db.json

{"egon": {"password": "123", "money": 3000}, "alex": {"password": "alex3714", "money": 30000}, "wsb": {"password": "3714", "money": 20000}}

 

#===============>common.py

from conf import settings

import logging

import logging.config

import json



def get_logger(name):

    logging.config.dictConfig(settings.LOGGING_DIC)  # 导入上面定义的logging配置

    logger = logging.getLogger(name)  # 生成一个log实例

    return logger





def conn_db():

    db_path=settings.DB_PATH

    dic=json.load(open(db_path,'r',encoding='utf-8'))

    return dic

 

#===============>access.log

[2017-10-21 19:08:20,285][MainThread:10900][task_id:core.src][src.py:19][INFO][登录成功]

[2017-10-21 19:08:32,206][MainThread:10900][task_id:core.src][src.py:19][INFO][登录成功]

[2017-10-21 19:08:37,166][MainThread:10900][task_id:core.src][src.py:24][ERROR][用户名不存在]

[2017-10-21 19:08:39,535][MainThread:10900][task_id:core.src][src.py:24][ERROR][用户名不存在]

[2017-10-21 19:08:40,797][MainThread:10900][task_id:core.src][src.py:24][ERROR][用户名不存在]

[2017-10-21 19:08:47,093][MainThread:10900][task_id:core.src][src.py:24][ERROR][用户名不存在]

[2017-10-21 19:09:01,997][MainThread:10900][task_id:core.src][src.py:19][INFO][登录成功]

[2017-10-21 19:09:05,781][MainThread:10900][task_id:core.src][src.py:24][ERROR][用户名不存在]

[2017-10-21 19:09:29,878][MainThread:8812][task_id:core.src][src.py:19][INFO][登录成功]

[2017-10-21 19:09:54,117][MainThread:9884][task_id:core.src][src.py:19][INFO][登录成功]

 

#介绍

# import logging

# logging.basicConfig(

#     # filename='access.log',

#     format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',

#     datefmt='%Y-%m-%d %H:%M:%S %p',

#     level=10

# )

#

# logging.debug('debug') # 10

# logging.info('info') # 20

# logging.warning('warn') #30

# logging.error('error') #40

# logging.critical('critial') #50

 

七、序列化(json与pickle)模块

1.8 常用模块

1、什么是系列化?

我们把对象从内部存款和储蓄器中变为可存款和储蓄或传输的进程称之为种类化,在Python中叫pickling,在其余语言中也被称之为serialization,marshalling,flattening等等,都以三个野趣。

1.8.1 日志模块的详细用法:

import logging

2、为何要连串化?

2.1:长久保存情状

需知一个软件/程序的施行就在拍卖一七种情景的改造,在编制程序语言中,'状态'会以多姿多彩有协会的数据类型(也可粗略的明亮为变量)的形式被保存在内部存款和储蓄器中。

内存是不能够永远保存数据的,当程序运维了一段时间,大家断电也许重启程序,内部存储器中有关这些顺序的从前一段时间的数码都被清空了。

在断电或重启程序在此之前将次第当前内部存款和储蓄器中全部的数量都封存下来,以便于后一次程序试行能够从文件中载入以前的数目,然后继续实践,那正是体系化。

切切实实的来讲,你玩任务召唤闯到了第13关,你保存游戏状态,关机走人,下一次再玩,还是可以从上次的职位上马一连闯关。或如,虚构机状态的挂起等。

2.2:跨平台数据交互

类别化之后,不仅可以够把种类化后的内容写入磁盘,还足以经过互连网传输到别的机器上,倘诺收发的两岸约定好实用一种连串化的格式,那么便打破了平台/语言差别化带来的界定,落成了跨平台数量交互。

扭曲,把变量内容从系列化的靶子重新读到内部存款和储蓄器里称之为反系列化,即unpickling。

1.8.2 Logger:产生日志

logger1=logging.getLogger('访谈日志')

# logger2=logging.getLogger('错吴日志')

3、怎么着种类化之json和pickle

json:

假若我们要在分歧的编制程序语言之间传递对象,就无法不把对象类别化为正规格式,比方XML,但更加好的秘籍是连串化为JSON,因为JSON代表出来就是三个字符串,能够被抱有语言读取,也足以方便地蕴藏到磁盘恐怕经过网络传输。JSON不仅仅是明媒正娶格式,况且比XML更加快,何况能够平素在Web页面中读取,特别便于。

JSON表示的目的就是规范的JavaScript语言的靶子,JSON和Python内置的数据类型对应如下:

图片 57

图片 58

图片 59图片 60

# =======================序列化与反序列化方法一  json.dumps=======================import jsonuser_dict={}name=input('名字:').strip()age=input('年龄:').strip()user_dict['name']=nameuser_dict['age']=ageuser_dict['is_beautiful']=Trueprint(user_dict)  #{'name': 'mogu', 'age': '19', 'is_beautiful': True}m=json.dumps(user_dict) # 这一步。。。with open('%s.json'%name,'w') as f:    f.write#==============================反序列化==========================================name=input('名字:').strip()with open('%s.json'%name,'r') as f:    msg=json.loadsprint

json连串化方法一图片 61图片 62

# =======================序列化与反序列化方法二  json.dump=======================import jsonuser_dict={}name=input('名字:').strip()age=input('年龄:').strip()user_dict['name']=nameuser_dict['age']=ageuser_dict['is_beautiful']=Trueprint(user_dict)  #{'name': 'mogu', 'age': '19', 'is_beautiful': True}#            这里无需再dumpswith open('%s.json'%name,'w') as f:    json.dump(user_dict,f) #传对象与文件# ==============================反序列化之 json.load==========================================name=input('名字:').strip()with open('%s.json'%name,'r') as f:    msg=json.load   #load  默认做了f.read()print

json系列化方法二图片 63图片 64

import json#dct="{'1':111}"#json 不认单引号#dct=str({"1":111})#报错,因为生成的数据还是单引号:{'one': 1}dct='{"1":"111"}'print(json.loads#conclusion:#        无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads

注意点!!!


pickle

图片 65

# =======================序列化与反序列化 pickle.dumps=======================import pickleuser_dict={}name=input('名字:').strip()age=input('年龄:').strip()user_dict['name']=nameuser_dict['age']=ageuser_dict['is_beautiful']=Trueprint(user_dict)  #{'name': 'mogu', 'age': '19', 'is_beautiful': True}m=pickle.dumps(user_dict) #序列化得到byteswith open('%s.pickle'%name,'wb')as f:  #注意w是写入str,wb是写入bytes,m是'bytes'    f.write# ==============================反序列化之 pickle.loads==========================================name=input('名字:').strip()with open('%s.pickle'%name,'rb') as f:    msg=pickle.loadsprint

情势其实与 json 大同小异

Pickle的主题素材和富有别的编制程序语言特有的连串化难题同样,就是它不得不用来Python,并且或者不一致版本的Python互相都不匹配,因而,只可以用Pickle保存那么些不主要的数额,不可能成功地反类别化也没涉及。

1.8.3 Filter:差非常的少不用

八、hashlib模块

1.8.4 Handler:接收Logger传过来的日记,进行日志格式化,能够打字与印刷到终点,也得以打字与印刷到文件

sh=logging.StreamHandler() #打字与印刷到顶点

fh1=logging.FileHandler('s1.log',encoding='utf-8')

fh2=logging.FileHandler('s2.log',encoding='utf-8')

 

1、什么叫hash:

hash是一种算法(3.x里替代了md5模块和sha模块,首要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法),该算法接受传入的内容,经过运算获得一串hash值。

1.8.5 Formatter:日志格式

formatter1=logging.Formatter(

    fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',

    datefmt='%Y-%m-%d %H:%M:%S %p',

)

formatter2=logging.Formatter(

    fmt='%(asctime)s : %(message)s',

    datefmt='%Y-%m-%d %H:%M:%S %p',

)

formatter3=logging.Formatter(

    fmt='%(asctime)s : %(module)s : %(message)s',

    datefmt='%Y-%m-%d %H:%M:%S %p',

)

 

 

2、hash的风味是:

2.1 只要传入的内容一样,得到的hash值必然一样=====>要用明文传输密码文件完整性校验

2.2 不能由hash值返解成内容=======》把密码做成hash值,不应该在网络传输明文密码

2.3 只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的

hash算法就如一座工厂,工厂接收你送来的原材质(能够用m.update()为工厂运送原材质),经过加工再次回到的出品就是hash值

import hashlibm=hashlib.md5()# m=hashlib.sha256()m.update('hello'.encode('utf8'))print(m.hexdigest  #5d41402abc4b2a76b9719d911017c592m.update('world'.encode('utf8'))print(m.hexdigest  #fc5e038d38a57032085441e7fe7010b0m2=hashlib.md5()m2.update('helloworld'.encode('utf8'))print(m2.hexdigest #fc5e038d38a57032085441e7fe7010b0'''注意:把一段很长的数据update多次,与一次update这段长数据,得到的结果一样但是update多次为校验大文件提供了可能。 '''

以上加密算法纵然如故特别了得,但存在缺陷,即:通过撞库能够反解。所以,有不能缺少对加密算法中增多自定义key再来做加密。

import hashlibm=hashlib.md5()m.update('world'.encode('utf8')) #7d793037a0760186574b0282f2f435e7print (m.hexdigestx = hashlib.md5('天王盖地虎'.encode('utf8'))x.update('world'.encode('utf8')) #26d7f494fd36ebcb1572fd41e5305b67print (x.hexdigest

图片 66图片 67

import hashlibpasswds=[    '123456',    '96875643',    'qweasd321',    'qaz987321',    '741852asd',    'zxc654123',    ]def make_passwd_dic:    dic={}    for passwd in passwds:        m=hashlib.md5()        m.update(passwd.encode('utf-8'))        dic[passwd]=m.hexdigest()    return dicdef break_code(cryptograph,passwd_dic):    for k,v in passwd_dic.items():        if v == cryptograph:            print('密码是===>33[46m%s33[0m' %k)cryptograph='6d57314243f721a1bbddb9ca405f285d'  #截取加密后的密文进行撞库(比如说密码是qaz987321)break_code(cryptograph,make_passwd_dic

仿照撞库破解密码

python 还会有二个 hmac 模块,它在那之中对我们成立 key 和 内容 进行更为的拍卖然后再加密:

import hmach = hmac.new('天王盖地虎'.encode('utf8'))h.update('hello'.encode('utf8'))print (h.hexdigest#1abaae8f65f68f2695a8545c5bc8e738#要想保证hmac最终结果一致,必须保证:#1:hmac.new括号内指定的初始key一样#2:无论update多少次,校验的内容累加到一起是一样的内容

1.8.6 、为handler绑定日志格式

sh.setFormatter(formatter1)

fh1.setFormatter(formatter2)

fh2.setFormatter(formatter3)

 

九、OS模块

os模块是与操作系统交互的多个接口

图片 68图片 69

import osBASE=os.path.dirname(__file__)path=os.path.join(BASE,'dbpath')os.getcwd()         #获取当前工作目录,即当前python脚本工作的目录路径os.chdir("dbpath")  #改变当前脚本工作目录;相当于shell下cdos.curdir           #返回当前目录: os.pardir           #获取当前目录的父目录字符串名:os.makedirs('dirname1/dirname2')  #  可生成多层递归目录os.removedirs('dirname1')         #  若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推os.mkdir('dirname')               #  生成单级目录;相当于shell中mkdir dirnameos.rmdir('dirname')               #  删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirnameos.listdir('dirname')             #  列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印os.remove(path+r'test.py')       #  删除一个文件os.rename("oldname","newname")    #  重命名文件/目录os.stat('path/filename')          #  获取文件/目录信息os.sep()       # 输出操作系统特定的路径分隔符,win下为"\",Linux下为"/"os.linesep()   # 输出当前平台使用的行终止符,win下为"tn",Linux下为"n"os.pathsep()   #  输出用于分割文件路径的字符串 win下为;,Linux下为:os.name()      # 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'os.system("bash command")  # 运行shell命令,直接显示os.environ()               # 获取系统环境变量os.popen(command[, mode[, bufsize]])  # 方法用于从一个命令打开一个管道。os.path.abspath                 # 返回path规范化的绝对路径os.path.split                   # 将path分割成目录和文件名二元组返回os.path.dirname                 # 返回path的目录。其实就是os.path.split的第一个元素os.path.basename                # 返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split的第二个元素os.path.exists   # 如果path存在,返回True;如果path不存在,返回Falseos.path.isabs    # 如果path是绝对路径,返回Trueos.path.isfile   # 如果path是一个存在的文件,返回True。否则返回Falseos.path.isdir    # 如果path是一个存在的目录,则返回True。否则返回Falseos.path.join(path1[, path2[, ...]])  # 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略os.path.getatime               # 返回path所指向的文件或者目录的最后存取时间os.path.getmtime               # 返回path所指向的文件或者目录的最后修改时间os.path.getsize                # 返回path的大小#==========================================os.walk()    #方法是一个简单易用的文件、目录遍历器,可以帮助我们高效的处理文件、目录方面的事情。#os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])参数#top     -- #是你所要遍历的目录的地址, 返回的是一个三元组(root,dirs,files)。    #root 所指的是当前正在遍历的这个文件夹的本身的地址    #dirs 是一个 list ,内容是该文件夹中所有的目录的名字    #files 同样是 list , 内容是该文件夹中所有的文件#topdown -- 可选, 为 True,则优先遍历 top 目录,否则优先遍历 top 的子目录。如果 topdown 参数为 True,walk 会遍历top文件夹,与top 文件夹中每一个子目录。#onerror -- 可选, 需要一个 callable 对象,当 walk 需要异常时,会调用。#followlinks -- 可选, 如果为 True,则会遍历目录下的快捷方式(linux 下是 symbolic link)实际所指的目录。

OS模块常用方法

os路径处理#方式一:推荐使用import os#具体应用import os,syspossible_topdir = os.path.normpath(os.path.join(    os.path.abspath(__file__),    os.pardir, #上一级    os.pardir,    os.pardir))sys.path.insert(0,possible_topdir)#方式二:不推荐使用os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

1.8.7 、为logger绑定handler

logger1.addHandler(sh)

logger1.addHandler(fh1)

logger1.addHandler(fh2)

 

十、sys模块

1 sys.argv           命令行参数List,第一个元素是程序本身路径2 sys.exit        退出程序,正常退出时exit3 sys.version        获取Python解释程序的版本信息4 sys.maxint         最大的Int值5 sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值6 sys.platform       返回操作系统平台名称

图片 70图片 71

#=========知识储备==========#进度条的效果[#             ][##            ][###           ][####          ]#指定宽度print('[%-15s]' %'#')print('[%-15s]' %'##')print('[%-15s]' %'###')print('[%-15s]' %'####')#打印%print('%s%%' % #第二个%号代表取消第一个%的特殊意义#可传参来控制宽度print('[%%-%ds]' %50) #[%-50s]print(('[%%-%ds]' %50) %'#')print(('[%%-%ds]' %50) %'##')print(('[%%-%ds]' %50) %'###')#=========实现打印进度条函数==========import sysimport timedef progress(percent,width=50):    if percent >= 1:        percent=1    show_str=('[%%-%ds]' %width) %(int(width*percent)*'#')    print('r%s %d%%' %(show_str,int(100*percent)),file=sys.stdout,flush=True,end='')#=========应用==========data_size=1025recv_size=0while recv_size < data_size:    time.sleep(0.1) #模拟数据的传输延迟    recv_size+=1024 #每次收1024    percent=recv_size/data_size #接收的比例    progress(percent,width=70) #进度条的宽度70

打字与印刷进程条图片 72图片 73

def __progress(self, recv_size, data_size, width=70):        ''' =========进度条==========    # data_size = 9292    # recv_size = 0    # while recv_size < data_size:    #     time.sleep  # 模拟数据的传输延迟    #     recv_size += 1024  # 每次收1024    #    #     percent = recv_size / data_size  # 接收的比例    #     progress(percent, width=70)  # 进度条的宽度70'''        percent = float(recv_size) / float(data_size)        if percent >= 1:            percent = 1        show_str = ('[%%-%ds]' % width) % (int(width * percent) * '>')        print('r%s %d%%' % (show_str, int(100 * percent)), file=sys.stdout, flush=True, end='')#==================================self.__progress(receive_size, file_size)#接受大小,总文件大小

FTP应用

1.8.8 设置日志品级:logger对象的日志等级相应<=handler的日记界别

# logger1.setLevel(50)

logger1.setLevel(10) #

sh.setLevel(10)

fh1.setLevel(10)

fh2.setLevel(10)

 

十一、random模块

import randomprint(random.random#----float    大于0且小于1之间的小数print(random.randint  #[1,3]    大于等于1且小于等于3之间的整数print(random.randrange #[1,3)    大于等于1且小于3之间的整数print(random.choice([1,'23',[4,5]]))#1或者23或者[4,5]print(random.sample([1,'23',[4,5]],2))#列表元素任意2个组合print(random.uniform#大于1小于3的小数,如1.927109612082716item=[1,3,5,7,9]random.shuffle #打乱item的顺序,相当于"洗牌"print

图片 74图片 75

import randomdef make_code:    res=''    for i in range:        s1=chr(random.randint #chr 代表参照ASCII表 转成对应字符        s2=str(random.randint(0,9))           res+=random.choice #取随机数拼凑    return resprint(make_code

随意验证码

1.8.9 测试

logger1.debug('测验着玩')

logger1.info('运转还算平常')

logger1.warning('大概要有bug了')

logger1.error('不好了,真tm出bug了')

logger1.critical('完犊子,推倒重写')

 

十二、别的模块加内置函数

链接地址:

      完成于:2018-09-0617:57:36

1.9 日志的存在延续

import logging

1.9.1 Logger:产出生之日志

logger1=logging.getLogger('root')

logger2=logging.getLogger('root.child1')

logger3=logging.getLogger('root.child1.child2')

 

1.9.2 Filter:大概不用

 

1.9.3 Handler:接收Logger传过来的日志,进行日志格式化,能够打字与印刷到终点,也得以打字与印刷到文件

sh=logging.StreamHandler() #打字与印刷到巅峰

 

1.9.4 Formatter:日志格式

formatter1=logging.Formatter(

    fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',

    datefmt='%Y-%m-%d %H:%M:%S %p',

)

 

 

1.9.5 为handler绑定日志格式

sh.setFormatter(formatter1)

 

1.9.6 为logger绑定handler

logger1.addHandler(sh)

logger2.addHandler(sh)

logger3.addHandler(sh)

 

1.9.7 设置日志品级:logger对象的日记等第相应<=handler的日志界别

# logger1.setLevel(50)

logger1.setLevel(10) #

logger2.setLevel(10) #

logger3.setLevel(10) #

sh.setLevel(10)

 

1.9.8 测试

logger1.debug('爷爷')

logger2.debug('爸爸')

logger3.debug('孙子')

 

1.10 正则模块

import re



# print(re.findall('w','egon 123 + _ - *'))

# print(re.findall('W','egon 123 + _ - *'))

# print(re.findall('s','egotn 12n3 + _ - *'))

# print(re.findall('S','egotn 12n3 + _ - *'))

# print(re.findall('d','egotn 12n3 + _ - *'))

# print(re.findall('D','egotn 12n3 + _ - *'))

# print(re.findall('n','egotn 12n3 + _ - *'))

# print(re.findall('t','egotn 12n3 + _ - *'))

# print(re.findall('e','egotn 12n3 +hello _ - *'))

# print(re.findall('^e','egotn 12n3 +hello _ - *'))

# print(re.findall('o$','egotn 12n3 +hello'))

 

#重复:.|?|*|+|{m,n}|.*|.*?

#.代表私行一个字符

# print(re.findall('a.b','a1b a b a-b aaaaaab'))

                    #   a.b

# print(re.findall('a.b','a1b a b anb a-b aaaaaab',re.DOTALL))

                    #   a.b

 

 

#?:代表?号左侧的字符出现0次依旧1

# print(re.findall('ab?','a ab abb abbbb a1b')) #['a','ab','ab','ab','a']

#                       #                  ab?

 

#*:代表*号左侧的字符出现0次照旧无穷次

# print(re.findall('ab*','a ab abb abbbb a1b')) #['a','ab','abb','abbbb','a']

                      #                  ab*

 

#+:代表+号左侧的字符现身1次可能无穷次

# print(re.findall('ab+','a ab abb abbbb a1b')) #['ab','abb','abbbb']

#                       #                  ab+

 

# {m,n}:代表侧边的字符出现m次到n次

# print(re.findall('ab{0,1}','a ab abb abbbb a1b')) #['ab','abb','abbbb']

# print(re.findall('ab?','a ab abb abbbb a1b')) #['ab','abb','abbbb']



# print(re.findall('ab{0,}','a ab abb abbbb a1b')) #['ab','abb','abbbb']

# print(re.findall('ab*','a ab abb abbbb a1b')) #['ab','abb','abbbb']



# print(re.findall('ab{1,}','a ab abb abbbb a1b')) #['ab','abb','abbbb']

# print(re.findall('ab+','a ab abb abbbb a1b')) #['ab','abb','abbbb']



# print(re.findall('ab{2,4}','a ab abb abbbb a1b')) #['abb', 'abbbb']

 

 

#.*:贪婪相配

# print(re.findall('a.*b','xxxy123a123b456b'))

                        #        a.*b

 

#.*?:非贪婪相称

# print(re.findall('a.*?b','xxxy123a123b456b'))

 

#|:或者

# print(re.findall('compan(y|iess)','too many companiess have gone bankrupt, and the next one is my company'))

# print(re.findall('compan(?:y|iess)','too many companiess have gone bankrupt, and the next one is my company'))

                                 #                                                                         compan(y|iess)



# print(re.findall('href="(.*?)"','<a href="http://www.baidu.com">点击我</a>'))

 

#rawstring:

# print(re.findall(r'a\c','ac a1c aBc')) #a\c->ac

 

#[]:取中括号内放肆的叁个

# print(re.findall('a[a-z]b','axb azb aAb a1b a-b a+b'))

# print(re.findall('a[A-Z]b','axb azb aAb a1b a-b a+b'))

# print(re.findall('a[a-zA-Z]b','axb azb aAb a1b a-b a+b'))

# print(re.findall('a[0-9]b','axb azb aAb a1b a-b a+b'))

# print(re.findall('a[-+*/]b','axb azb aAb a1b a-b a+b'))

# print(re.findall('a[^-+*/]b','axb azb aAb a1b a-b a+b'))

 

#re模块的其余措施

#re.search :只非常成功二遍就回到

# print(re.search('a[*]b','axb azb aAb a1b a-b a+b'))

# print(re.search('a[0-9]b','axb azb aAb a1b a-b a2b a+b').group())

 

# re.match:从早先取

# print(re.match('a[0-9]b','axb azb aAb a1b a-b a2b a+b'))

# print(re.match('a[0-9]b','a1b axb azb aAb a1b a-b a2b a+b').group())

# print(re.search('^a[0-9]b','a1b axb azb aAb a1b a-b a2b a+b').group())

 

# re.split

# print(re.split(':','root:x:0:0::/root:/bin/bash',maxsplit=1))

# 'root:x:0:0::/root:/bin/bash'.split(':')

 

# re.sub

# print(re.sub('root','admin','root:x:0:0::/root:/bin/bash',1))

 

#了解

# print(re.sub('^([a-z]+)([^a-z]+)(.*?)([^a-z]+)([a-z]+)$',r'52341','root:x:0:0::/root:/bin/bash'))

 

# re.compile

obj=re.compile('ad{2}b')

print(obj.findall('a12b a123b a12345b abbb'))

print(obj.search('a12b a123b a12345b abbb').group())

 

1.11 时间模块

import time

#掌握

# print(time.time())



# print(time.localtime())

# print(time.localtime().tm_mday)

# print(time.gmtime())



# print(time.strftime('%Y-%m-%d %H:%M:%S'))

# print(time.strftime('%Y-%m-%d %X'))

 

#了解

# print(time.localtime(11111111))

# print(time.localtime(time.time()))

# print(time.gmtime(time.time()))



# print(time.mktime(time.localtime()))



# print(time.strftime('%Y-%m-%d',time.localtime()))

# print(time.strptime('2017-03-01','%Y-%m-%d'))



# print(time.asctime(time.localtime()))

# print(time.ctime(111111))

 

 

#datetime

import datetime

# print(datetime.datetime.now())

# print(datetime.datetime.fromtimestamp(111111111))



# print(datetime.datetime.now()+datetime.timedelta(days=3))

# print(datetime.datetime.now()+datetime.timedelta(days=-3))

# print(datetime.datetime.now()+datetime.timedelta(hours=3))

# print(datetime.datetime.now()+datetime.timedelta(minutes=3))

# print(datetime.datetime.now()+datetime.timedelta(seconds=3))



# print(datetime.datetime.now().replace(year=1999,hour=12))

 

本文由金沙澳门官网送注册58发布于编程应用,转载请注明出处:模块与包,包与模块

关键词: