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 
  • 相关阅读:
    SORT ORDER BY STOPKEY
    javaScript 数值型和字符串型之间的转换
    Caused by: org.apache.ibatis.type.TypeException: Could not resolve type alias 'Student'
    Caused by: java.sql.SQLException: Field 'stu_id' doesn't have a default value
    Result Maps collection does not contain value for StudentMapper.StudentMap
    集群维护
    logstash 调用exec
    logstash zabbix插件
    logstash 调用脚本告警
    Caused by: java.lang.NoSuchMethodException: com.you.entity.sys.Param.()
  • 原文地址:https://www.cnblogs.com/tianjie0522/p/5563258.html
Copyright © 2011-2022 走看看