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 https://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 https://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'\x80\x03]q\x00(X\x04\x00\x00\x00nameq\x01K{X\x03\x00\x00\x00jobq\x02e.'
 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 

 

posted @ 2016-06-07 16:14  也敲寡妇门  阅读(246)  评论(0编辑  收藏  举报