zoukankan      html  css  js  c++  java
  • python基础篇【第五篇】模块,生成器

    一、字符转格式化

        在python 中目前使用的字符串格式化有两种 % ,format;建议使用format方式,百分号方式是比较古老的,而format方式比较新,相比百分号方式功能较全,有替换古老方式的趋势,目前并存。

     1、百分号方式:

    %[(name)][flags][width].[precision]typecode

    name  可选, 用于选择指定的key

    flages  可选,可提供选择值有:

    辅助符号 说明
    - 用做左对齐;正数前无符号,负数前加符号
    + 在右对齐;正数前加正号,负数前加负号
     0  显示的数字前面填充“0”而不是默认的空格

      

    格式化符号 说明
    %s 优先用str()函数进行字符串转换,并格式化的指定位置
    %d 转成十进制数,并格式化的指定位置
    %o 转成八进制数,并格式化的指定位置
    %x

    转成十六进制数,并格式化的指定位置

    %e/%E  转成科学计数法,并格式化的指定位置(e,E就是输出的时候大小写区别)
    %c 将十进制数转换为其unicode对应的值是字符,并把字符添加到指定位置
    %f/%F 转成浮点型,并格式化的指定位置(默认保留小数点后6位)
    %g/%G 自动调整将整数,浮点数转换成浮点或科学计数法(超过6位数用科学计数法)
    % 字符串中出现占位符,两个%表示一个%,不出现占位符,就无所谓

     

    width :表示占有宽度

    下面列举了几个例子:

     1 test1="my name is %s" %"xiaoma"
     2 print(test1)
     3 #结果
     4 my name is xiaoma
     5 
     6 test2="my name is %s age%d" %("tianjie",18)
     7 print(test2)
     8 #结果
     9 my name is tianjie age18
    10 
    11 test3="my name is %(name)s , age %(age)d" %{"name":"dbq","age":18}
    12 print(test3)
    13 #结果
    14 my name is dbq , age 18
    15 
    16 test4="percent %.2f" %89.123345   #保留两位小数点
    17 print(test4)
    18 #结果
    19 percent 89.12
    20 
    21 test5="percent %(xiao).2f %%" %{"xiao":123.1233465}
    22 #一个百分号会报错的
    23 print(test5)
    24 #结果
    25 percent 123.12 %
    26 
    27 charA = 65
    28 charB = 66
    29 print("ASCII码65代表:%c" % charA)
    30 print("ASCII码66代表:%c" % charB)
    31 Num1 = 0xEF3
    32 Num2 = 0xAB03
    33 print('转换成十进制分别为:%u和%u' % (Num1, Num2))
    34 Num3 = 1200000
    35 print('转换成科学计数法为:%e' % Num3)
    36 
    37 #输出结果:
    38 ASCII码65代表:A
    39  ASCII码66代表:B
    40 转换成十进制分别为:3827和43779
    41 转换成科学计数法为:1.200000e+06

     注意:百分号方式没有二进制转换方式,

    2、format格式化方式

    字符串的参数使用{NUM}进行表示,0, 表示第一个参数,1, 表示第二个参数, 以后顺次递加;

    使用":", 指定代表元素需要的操作, 如":.3"小数点三位, ":8"占8个字符空间等 

    还可以添加特定的字母, 如:

    'b' - 二进制. 将数字以2为基数进行输出.

    'c' - 字符. 在打印之前将整数转换成对应的Unicode字符串.

    'd' - 十进制整数. 将数字以10为基数进行输出.

    'o' - 八进制. 将数字以8为基数进行输出.  

    'x' - 十六进制. 将数字以16为基数进行输出, 9以上的位数用小写字母.

    'e' - 幂符号. 用科学计数法打印数字, 用'e'表示幂.  

    'g' - 一般格式. 将数值以fixed-point格式输出. 当数值特别大的时候, 用幂形式打印. 

    'n' - 数字. 当值为整数时和'd'相同, 值为浮点数时和'g'相同. 不同的是它会根据区域设置插入数字分隔符. 

    '%' - 百分数. 将数值乘以100然后以fixed-point('f')格式打印, 值后面会有一个百分号. 

    数字(0, 1, ...)即代表format()里面的元素, 所以可以使用"."调用元素的方法;

     还有一些辅助符号:

      <,左对齐

      >,右对齐

      ^,内容居中

      =,内容右对齐,将符号放置在填充字符的左侧,且只对数字类型有效。

    还是看一下实际运用更加一目了然:

     1 for1="my name is {},age {},job {}".format("dbp",18,"IT")
     2 print(for1)
     3 #执行结果
     4 my name is dbp,age 18,job IT
     5 
     6 for2="my name is {},age {},job {}".format(*["dbp",18,"IT"])
     7 #后面加*表示也可以导入一个列表变量
     8 print(for2)
     9 #执行结果
    10 my name is dbp,age 18,job IT
    11 
    12 for3 = "my name is {0},age {1},job {0}".format("qqq",18)
    13 #可以根据索引值调用
    14 print(for3)
    15 #执行结果
    16 my name is qqq,age 18,job qqq
    17 
    18 for4="my name is {name},age {age},job {job} ".format(**{"name":"tianjie","age":19,"job":"IT"})
    19 #加两个* 可以导入字典,根据key调用
    20 print(for4)
    21 #执行结果
    22 my name is tianjie,age 19,job IT 
    23 
    24 for5="my name is {0[0]},age {0[1]},job {1[2]}".format(["tianjie",123,"hello"],["dbq","banking",234])
    25 print(for5)
    26 #执行结果
    27 my name is tianjie,age 123,job 234
    28 
    29 for6="my name is {:s},age {:d},money {:f}".format("tianjie",18,2222.1)
    30 #字符、整数、浮点数
    31 print(for6)
    32 #执行结果
    33 my name is tianjie,age 18,money 2222.100000
    34 
    35 for7="i am {name:s}, age {age:d}, job {job:s}".format(**{"name": "admin", "age": 18,"job":"banking"})
    36 print(for7)
    37 #执行结果
    38 i am admin, age 18, job banking
    39 
    40 for8="numbers: {:#b},{:#o},{:#d},{:#x},{:#X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
    41 print(for8)
    42 #转换为二进制、八进制、十六进制、百分数(不加#表示显示结果没有0b、0o、0x)
    43 numbers: 0b1111,0o17,15,0xf,0XF, 1587.623000%
    44 
    45 for9="numbers: {0:#b},{0:#o},{0:#d},{0:#x},{1:#X}, {2:%}".format(15,56,0.9897763)
    46 print(for9)
    47 #执行结果
    48 numbers: 0b1111,0o17,15,0xf,0X38, 98.977630%

    二、迭代器,生成器,递归

    1、迭代器


    刚开始的时候一直认为,可以被 for循环的的对象,就为迭代器,下面是更严谨的解释!

    迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件

    特点:

    1. 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
    2. 不能随机访问集合中的某个值 ,只能从头到尾依次访问
    3. 访问到一半时不能往回退
    4. 便于循环比较大的数据集合,节省内存

    总之就是,可以通过_next_去取,需要一个取一个,而不是把元素,一整个加进内存,你可以迭代不是序列但表现处序列行为的对象,例如字典的键、一个文件的行,或者一个字符串!如以下事例:

     1 name=iter("hello")
     2 print(name.__next__())
     3 print(name.__next__())
     4 print(name.__next__())
     5 print(name.__next__())
     6 print(name.__next__())
     7 
     8 #执行结果
     9 h
    10 e
    11 l
    12 l
    13 o

    2、生成器

    一个函数调用时返回一个迭代器,那这个函数就叫生成器(generator),只要看到函数中出现yield,那么这个函数就是生成器;如以下实例:

     1 import time
     2 def func(num):
     3     a=0
     4     while True:
     5         a+=1
     6         if a>=num:
     7             return
     8         else:
     9             yield a
    10 
    11 test=func(5)
    12 print(test)
    13 for i in test:
    14     print(i)
    15     time.sleep(1)   #停一秒在显示
    16 
    17 #执行结果
    18 <generator object func at 0x0000003668194A40>
    19 1
    20 2
    21 3
    22 4

    3、递归

    在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

    递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

    使用递归函数需要注意防止栈溢出,不能写入死的循环没有结束值。

    如示例:计算斐波那契数列0,1,1,2,3,5,8,13,21,34,55,89.。。。。。。

     1 def func(arg1,arg2,stops):
     2     if arg1==0:
     3         print(arg1,arg2)
     4     arg3=arg1+arg2
     5     print(arg3)
     6     if arg3<stops:
     7         func(arg2,arg3,stops)
     8     else:
     9         return
    10 
    11 func(0,1,20)   #结束值20
    12 #执行结果
    13 0 1
    14 1
    15 2
    16 3
    17 5
    18 8
    19 13
    20 21

    练习实例:

    用递归计算1*2*3*4*5*6*7结果:

     1 def func(num):
     2     if num==1:
     3         return num
     4     else:
     5         return num * func(num-1)
     6 print(func(7))
     7 
     8 #执行过程
     9 
    10 # func(7)
    11 # 7*func(6)
    12 # 7*(6*func(5))
    13 # 7*(6*(5*func(4)))
    14 # 7*(6*(5*(4*func(3))))
    15 # 7*(6*(5*(4*(3*func(2)))))
    16 # 7*(6*(5*(4*(3*(2*(func(1)))))))
    17 # 7*(6*(5*(4*(3*(2*1)))))
    18 # 7*(6*(5*(4*(3*2))))
    19 # 7*(6*(5*(4*6)))
    20 # 7*(6*(5*24))
    21 # 7*(6*120)
    22 # 7*720
    23 # 5040

    三、模块

    随着代码越写越多,功能越来越多,你不能把所有的代码都写在一个文件中,不方便查询排错,那么我们就想着把一个功能放在一个文件中,或者一个函数。

    在python中一个.py的文件就称之为一个模块;在其他语言中如Java、c# 等叫做类库。

    模块有三种:

      内置模块

      第三方模块

      自定义模块

    1.自定义模块    

    自定义模块,就是根据功能需求自己写的py文件,供功能调用

    要想使用模块首先要导入模块,下面列举几个导入模块的例子:

     1 # import digui
     2 #
     3 # digui.login()
     4 #
     5 # from test import mokuai
     6 # from test import mokuai as rename
     7 # from  test import file
     8 # import test_ll.file
     9 # test_ll.file.func()
    10 # # mokuai.func(3)
    11 import requests

    导入模块时是根据哪个路径作为基准来进行的呢:sys.path

     1 import sys
     2 print(sys.path)
     3 #返回结果
     4 ['E:\python课程\day5',
     5  'E:\python课程', 
     6 
     7 'C:\Users\Administrator\AppData\Local\Programs\Python\Python35\python35.zip', 
     8 
     9 'C:\Users\Administrator\AppData\Local\Programs\Python\Python35\DLLs', 
    10 
    11 'C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib', 
    12 
    13 'C:\Users\Administrator\AppData\Local\Programs\Python\Python35', 
    14 
    15 'C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-packages']

    如果用sys.path路径表没有你想要的路径,可以通过sys.path.append("路径")添加。

    sys.path路径首先是从程序本目录中查找,

    注:模块取名字时一定不能与标准库的名字一样

    2、第三方模块

     下载安装第三方模块有两种方法:

    1、是用yum、pip3/pip、apt-get   

    #requests 发送get请求的
    pip3安装   
    pip3 install requests

    2、源码安装

     1 # pycrypto,由于 paramiko 模块内部依赖pycrypto,所以先下载安装pycrypto
     2  
     3 # 下载安装 pycrypto
     4 wget http://files.cnblogs.com/files/wupeiqi/pycrypto-2.6.1.tar.gz
     5 tar -xvf pycrypto-2.6.1.tar.gz
     6 cd pycrypto-2.6.1
     7 python setup.py build
     8 python setup.py install
     9  
    10 # 进入python环境,导入Crypto检查是否安装成功
    11  
    12 # 下载安装 paramiko
    13 wget http://files.cnblogs.com/files/wupeiqi/paramiko-1.10.1.tar.gz
    14 tar -xvf paramiko-1.10.1.tar.gz
    15 cd paramiko-1.10.1
    16 python setup.py build
    17 python setup.py install
    18  
    19 # 进入python环境,导入paramiko检查是否安装成功

    序列化

    json和pickle两个模块

      json,用于字符串和python基本数据类型间进行转换,可以跨语言!

      pickle,用于python所有的类型间转换,但是只能在python语言中用,其它语言解释不了!

    Json模块有四个功能:

          dumps:没有写入文件,把数据类型转化为所有程序语言都认识的字符串,

          dump:把数据类型转化为所有程序语言都认识的字符串,并写入文件

          loads:在Python中反序列化,把字符串转化为数据类型,且字符串中的元素要用双引号

          load:读取文件中的字符串,并转换python的基础类型

    如以下实例:

     1 import json
     2 li=["name",123,"job"]
     3 js=json.dumps(li)
     4 print(js,type(js))
     5 #执行结果
     6 ["name", 123, "job"] <class 'list'>
     7 
     8 li='["name",123,"job"]'
     9 js=json.loads(li)
    10 print(js,type(js))
    11 #执行结果
    12 ['name', 123, 'job'] <class 'list'>
    13 
    14 li=["name",123,"job"]   
    15 with open("test","w") as f:
    16     json.dump(li,f)
    17 #把列表转换为字符,写入同级目录中的test文件中
    18 
    19 with open("test","r") as f:   #打开文件,把文件中的内容转换成对应类型
    20     li=json.load(f)
    21 print(li,type(li))
    22 #执行结果
    23 ['name', 123, 'job'] <class 'list'>

    pickle也是有四个模块:

      dumps、dump、loads、load

    给json功能一样,只不过转换过的内容只有python自己能解释:

     1 import pickle
     2 li=["name",123,"job"]
     3 test=pickle.dumps(li)
     4 print(test)
     5 #执行结果 是python二进制格式
     6 b'x80x03]qx00(Xx04x00x00x00nameqx01K{Xx03x00x00x00jobqx02e.'
     7 
     8 
     9 #转换回来时必须也要是二进制格式
    10 test1=pickle.loads(test)
    11 print(test1,type(test1))
    12 #执行结果
    13 ['name', 123, 'job'] <class 'list'>
    14 
    15 li=["name",123,"job"]   #以二进制方式写入文件中
    16 with open("db","wb") as f:
    17     pickle.dump(li,f)
    18 #如字样    �]q (X   nameqK{X   jobqe.
    19 
    20 
    21 with open("db","rb") as f:  #到文件里取出来
    22     li=pickle.load(f)
    23 print(li,type(li))
    24 #执行结果
    25 ['name', 123, 'job'] <class 'list'>

     time模块:

    时间模块有三种表示方式:

      时间戳:        1970年1月1日之后的秒,可以用time.time()获取

      格式化的字符串    2016-06-07 12:12:12, 用tiem.strftime('%Y-%m-%d %H:%M:%S')

      结构化时间     元组包括了:年、月、日、星期等 , 用tiem.localtime()

    实际运用:

     1 import time
     2 import datetime
     3 
     4 print(time.time())  #返回当前系统时间戳 如 1465279434.84525
     5 
     6 print(time.ctime())  #返回当前时间 Tue Jun  7 14:03:54 2016
     7 
     8 print(time.ctime(time.time()-86640*2)) #将时间戳转换成时间格式 ,两天前 Sun Jun  5 13:55:54 2016
     9 
    10 print(time.gmtime(time.time()-86640))  #将时间戳转换成struct_time格式格林昨天时间
    11 #time.struct_time(tm_year=2016, tm_mon=6, tm_mday=6, tm_hour=5, tm_min=59, tm_sec=54, tm_wday=0, tm_yday=158, tm_isdst=0)
    12 
    13 print(time.localtime(time.time()-86640))  #将时间戳转换成strut_time格式,但返回的是本地昨天时间
    14 #time.struct_time(tm_year=2016, tm_mon=6, tm_mday=6, tm_hour=13, tm_min=59, tm_sec=54, tm_wday=0, tm_yday=158, tm_isdst=0)
    15 
    16 print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())) #将结构化的strut_time格式转换为,时间字符传格式 2016-06-07 14:03:54
    17 
    18 print(time.strptime("2016-06-07","%Y-%m-%d"))#与上相反将时间字符串格式,转化为strut_time格式
    19 #time.struct_time(tm_year=2016, tm_mon=6, tm_mday=7, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=159, tm_isdst=-1)
    20 
    21 
    22 #datetime 模块
    23 print(datetime.date.today()) #输出格式时期格式年月日 2016-06-07
    24 print(datetime.date.fromtimestamp(time.time()-86440))#将时间戳格式转化成日期格式 2016-06-06
    25 print(datetime.datetime.now())   #显示当前时间详细如:2016-06-07 13:21:12.199884 毫秒都有
    26 
    27 time_s1=datetime.datetime.now()
    28 print(time_s1.utctimetuple())     #显示出strut_time格式
    29 print(time_s1.replace(2015,5,22)) #显示当前时间,但把日期换成了2015-05-22
    30 
    31 time_s2=datetime.datetime.strptime("21/11/16 17:50","%d/%m/%y %H:%M")#将字符串转换成日期格式
    32 new_date=datetime.datetime.now()+datetime.timedelta(days=10)#比现在加10天 2016-06-17 13:57:47.737319
    33 new_date1=datetime.datetime.now()+datetime.timedelta(days=-10)#比现在减10天 2016-05-28 13:59:53.181695
    34 new_date2=datetime.datetime.now()+datetime.timedelta(hours=-10) #比现在减10小时 2016-06-07 04:01:27.349964
    35 new_date3=datetime.datetime.now()+datetime.timedelta(seconds=-10) #比现在减10秒 2016-06-07 14:02:45.919412
    View Code

    logging模块:

    Python 使用logging模块记录日志涉及四个主要类,使用官方文档中的概括最为合适:

    logger    提供了应用程序可以直接使用的接口;

    handler  将(logger创建的)日志记录发送到合适的目的输出;

    filter  提供了细度设备来决定输出哪条日志记录;

    formatter  决定日志记录的最终输出格式。

    Handlers:
    handler对象负责发送相关的信息到指定目的地。

    Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Logger可以把信息输出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler

    常用的Handlers有两种:

      StreamHandler() 显示到屏幕上
      FileHandler(filename[,mode]) 写到文件中
    filename是文件名,必须指定一个文件名。
    mode是文件的打开方式。参见Python内置函数open()的用法。默认是’a',即添加到文件末尾。

    Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
    Handler.setFormatter():给这个handler选择一个格式
    Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象

    日志模块,分为debug(),info(),warning(),error(),critical()级别;

    日志级别大小关系为:CRITICAL > ERROR > WARNING > INFO > DEBUG 

    默认是从WARNING级别将log 打印到屏幕如:

     1 import logging
     2 
     3 logging.debug("hello debug")
     4 logging.info("hello info")
     5 logging.warning("hello warning")
     6 logging.error("hello error")
     7 logging.critical("server is down")
     8 
     9 #执行结果
    10 WARNING:root:hello warning
    11 ERROR:root:hello error
    12 CRITICAL:root:server is down

    简单用法

     1 logging.basicConfig(level=logging.DEBUG,
     2                     format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s %(name)s ',
     3                     datefmt='%Y-%m-%d %H:%M:%S',
     4                     filename='myapp.log',
     5                     filemode='w')
     6 
     7 logging.debug('This is debug message')
     8 logging.info('This is info message')
     9 logging.warning('This is warning message')
    10 
    11 #./myapp.log文件里的信息如下
    12 2016-06-07 15:11:29 logger.py[line:17] DEBUG This is debug message root 
    13 2016-06-07 15:11:29 logger.py[line:18] INFO This is info message root 
    14 2016-06-07 15:11:29 logger.py[line:19] WARNING This is warning message root 

    logging.basicConfig函数各参数:
    filename: 指定日志文件名
    filemode: 和open函数意义相同,指定日志文件的打开模式,'w'或'a'
    format: 指定输出的格式和内容,format可以输出很多有用信息,如上例所示:
     %(levelno)s: 打印日志级别的数值
     %(levelname)s: 打印日志级别名称
     %(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
     %(filename)s: 打印当前执行程序名
     %(funcName)s: 打印日志的当前函数
     %(lineno)d: 打印日志的当前行号
     %(asctime)s: 打印日志的时间
     %(thread)d: 打印线程ID
     %(threadName)s: 打印线程名称
     %(process)d: 打印进程ID
     %(message)s: 打印日志信息
    datefmt: 指定时间格式,同time.strftime()
    level: 设置日志级别,默认为logging.WARNING

    把日志同时输出屏幕和文件:

    这个很牛逼的,可以限制级别写到屏幕或者文件,以下实例我就是把DEBUG级别以上的写到文件中,把INFO级别以上的直接在屏幕显示:

     1 import logging
     2 logging.basicConfig(level=logging.DEBUG,
     3                     format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s %(name)s ',
     4                     datefmt='%Y-%m-%d %H:%M:%S',
     5                     filename='myapp.log',
     6                     filemode='w')
     7 
     8 
     9 display=logging.StreamHandler()
    10 display.setLevel(logging.INFO)  #设置级别
    11 formater=logging.Formatter("%(name)s %(asctime)s %(levelname)s %(message)s")     #格式化定义规则
    12 datefmt='%Y-%m-%d %H:%M:%S'    #时间格式
    13 display.setFormatter(formater)         #导入格式化
    14 logging.getLogger("").addHandler(display)  #返回一个logger对象,如果没有指定名字将返回root logger
    15 
    16 logging.debug('This is debug message')
    17 logging.info('This is info message')
    18 logging.warning('This is warning message')
    19 
    20 #屏幕上打印
    21 root 2016-06-07 15:31:21,137 INFO This is info message
    22 root 2016-06-07 15:31:21,137 WARNING This is warning message
    23 
    24 #./myapp.log文件中内容为:
    25 2016-06-07 15:31:21 logger.py[line:25] DEBUG This is debug message root 
    26 2016-06-07 15:31:21 logger.py[line:26] INFO This is info message root 
    27 2016-06-07 15:31:21 logger.py[line:27] WARNING This is warning message root 
  • 相关阅读:
    洛谷—— P3353 在你窗外闪耀的星星
    洛谷—— P1238 走迷宫
    洛谷—— P1262 间谍网络
    9.8——模拟赛
    洛谷—— P1189 SEARCH
    算法
    May 22nd 2017 Week 21st Monday
    May 21st 2017 Week 21st Sunday
    May 20th 2017 Week 20th Saturday
    May 19th 2017 Week 20th Friday
  • 原文地址:https://www.cnblogs.com/tianjie0522/p/5563258.html
Copyright © 2011-2022 走看看