Python中的內置模塊與生成器迭代器-day5

  • Python3 中內置模塊
  • Python中的列表生成式
  • Python生成器
  • Python迭代器

 Pytho一切皆對象,把你想用到的東西保存成一個對象(變量)這樣是沒有錯的無論你是想調用仍是拿它作文章。python

1、Python中的內置模塊

  PS:做爲一個新手若是你不想使用IDE又想使用Python中的自動補全,能夠下載使用ipython。下面實例中也大可能是ipython輸入和輸出的內容。git

  安裝ipython:pip3 install ipythonshell

Python3-內置函數
     - abs() 絕對值
     - all() 都爲真
     - any() 有一個爲真
     - ascii() 把字符串轉換成ASCII
     - bin() 二進制格式
     - bool() 布爾值
     - bytearray() 經過該ASCII碼對應修改字符串

 

     - bytes() bytes格式
     - callable 是否能夠被調用(帶上括號的就是能夠被調用的)
     - chr 把數字轉換對應的ASCII碼轉換成字符
     - compile 把一個代碼文件加載進來,按exec 或者eval的方式執行
     - exec 執行字符串代碼
     - eval 把字符串形式的表達式,解析並執行
     - dir 把一個對象全部的方法展現出來
     - divmod 返回餘數和商
     - format 格式化字符串
     - frozenset 不可變集合
     - globals 顯示當前程序的全局表量
     - hash 把一個字符串轉換成一個hash的數值
     - hex 把一個數字轉換成十六進制
     - 內存得知
     - isinstance 判斷一個對象是否是一個實例
     - iter()
     - len() 字符長度
     - 以字典的形式打印局部變量
     - max() 最大值
     - min() 最大值
     - ort(0 把一個數字改爲8進制
     - ord() 把字符串轉換成ASCII碼
     - pow(2,3) 2 的3 次冪
     - reversed 反轉
     - round 四捨五入
     - 
 
 

2、列表生成式

  概念:列表生成式能夠簡單理解成是將原來的列表轉換成一個有規律的新列表;這裏比方將原來的列表a中的全部大於5的數據所有加一。這時候你確定會想到直接用for循環作這件事,事實上也是能夠的;可是因爲爲了更加節省代碼,也有如下這幾種策略。json

  - 最熟悉的for循環windows

1 a = [0,1,2,3,4,5,6,7,8,9,10]
2 
3 for i in a:
4     a[i] = i + 1
5 
6 print(a)
7 
8 
9 #這個實例若是想將生成好的列表賦值到原來的列表中實際上是有不少限制的好比說當前的列表必須是用0開始,第二每一個直接的數值相差也必須是1

  - 活學活用的enumeratebash

1 a = [1,2,3,5,7,7,9,10,11]
2 
3 for index,i in enumerate(a):
4     a[index] += 1
5 
6 print(a)

  - 列表生成器併發

 1 #簡單實現功能 so easy
 2 
 3 
 4 a = [1,2,3,5,7,7,9,10,11]
 5 
 6 a = [i + 1 for i in a]
 7 print(a)
 8 
 9 #支持三元運算
10 
11 a = [1,2,3,5,7,7,9,10,11]
12 
13 a = [i * i if i > 5 else i for i in a]
14 
15 print(a)
16 #這裏咱們將列表中全部的數據只要大於5,都自乘
裝逼必備

  - 列表生成器直接的步驟dom

 

3、生成器

  經過列表生成器,咱們能夠直接獲得一個新列表,可是咱們知道列表是有長度的,並且之間建立一個大的列表是很消耗內存的。若是當咱們建立一個列表的時候咱們僅須要前面的某些元素,後面的空間也會白白浪費。這時咱們就可讓這個列表一個一個生成,這就是生成器(generator)ide

  - 建立一個生成器也很簡單隻須要吧中括號改爲小括號就行函數

a = [1,3,5,6,7,8,9,11,13,15]
a = (i * i if i == 9 else i + 5 for i in a)
print(a)

print(next(a))  #等於 a.__next__()

for i in a:
    print('geerator:',i)

  - 經過運行上面代碼咱們能夠發現第一個print只返回了一個6,這是爲何呢,可是仔細一看個人條件是隻有等於9的才相乘,其餘的都是自加5,二列表中的第一個書就是一個1,1+5這個算數這個就不用多說了,值得一說的就是生成器是一個對象,也就是能夠被調用的,經過for循環能夠將列表中多有的數字遍歷一遍,而若是咱們是一個一個next()直到最後一個不只傻並且大多數的時候你並不知道這個列表的長度,一旦超過列表真實長度就會拋出異常。

 

  - 斐波拉契數列(這個不會刻意理解)

def fib(max):
    n,a,b = 0,0,1 #n==max是次數,a是初始值,b=1
    while n < max
        print(b)
        a,b = b,a+b
        n = n + 1
    return 'break'

  - 什麼是斐波拉契:簡單的說就是後面的數,等於前面的兩個數相加,咱們調用上面的函數,比方說flb(10)這個函數就會循環十次,會直接十次的數字所有打印出來,若是這個時候咱們想一個一個打印出來呢?

 

  - 生成器的fib

  

def fib(max):
    n,a,b = 0,0,1 #n==max是次數,a是初始值,b=1
    while n < max:
        #print(b)
        yield b
        a,b = b,a+b
        n = n + 1
    return 'break' 

f = fib(6) # --> 生成器

 

  -- 串行生成器

  什麼是串行生成器:串行生成器就是generator對象被反覆調用期間作其餘的一些工做,好比說執行一個函數。

 

  - 吃包子程序(實在是想不出其餘的東西了,實際上是不想寫)

import time

def consumer(name):
    print("開始吃包子了"%name)
    while True:
        baozi = yield
        print("包子%s來了,被%s!"%(baozi,name))


def producer(name):
    c = consumer("Leon")
    c1 = consumer("CHEN")
    c.__next__()
    c1.__next__()
    
    print("開始吃包子了")
    for i in range(10):
        time.sleep(1)
        print("作了兩個包子")
        c.send(i)   # send方法能夠將指傳入到上面的yield對應的變量
        c1.send(i)

producer("MA")

這個列子只須要知道,使用生成器能夠實現假併發,實際是串行,和yield是能夠賦值,而且使用seed是能夠向生成器中傳值得。

 

4、迭代器

  在寫迭代器以前,咱們須要知道什麼數據類型是能夠被迭代的(能夠被for循環)。

  - 字典

  - 列表

  - 字符串

  - 生成器

 

  -  那些數據類型是迭代器

>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False

  - 生成器都是Iterator對象,但listdictstr雖然是Iterable,卻不是Iterator

 

小結

  - 凡是可做用於for循環的對象都是Iterable類型;

  - 凡是可做用於next()函數的對象都是Iterator類型,它們表示一個惰性計算的序列;

  - 集合數據類型如listdictstr等是Iterable但不是Iterator,不過能夠經過iter()函數得到一個Iterator對象。

 

5、經常使用模塊

  - time 模塊

In [1]: import time

In [2]: time.time()  #顯示時間戳
Out[2]: 1508836530.6026018

In [3]: time.gmtime()  #UTC的時間對象
Out[3]: time.struct_time(tm_year=2017, tm_mon=10, tm_mday=24, tm_hour=9, tm_min=15, tm_sec=51, tm_wday=1, tm_yday=297, tm_isdst=0)

In [4]: t = time.gmtime() #取出對象中的年月日

In [5]: t.tm_year
Out[5]: 2017

In [6]: t.tm_mon
Out[6]: 10

In [7]: time.clock()#老子也不知道是啥反正沒有用就是了
Out[7]: 2.8444452535310943e-07

In [8]: time.asctime() 返回時間格式
Out[8]: 'Tue Oct 24 17:17:05 2017'

In [10]: time.localtime() #和上面的gmtime差很少只不過是本地的時間對象
Out[10]: time.struct_time(tm_year=2017, tm_mon=10, tm_mday=24, tm_hour=17, tm_min=28, tm_sec=38, tm_wday=1, tm_yday=297, tm_isdst=0)

In [12]: time.strftime("%Y-%m-%d %H:%M:%S")  #自定義時間
Out[12]: '2017-10-24 17:31:09'

  時間戳與字符串形式的時間之間的轉換

In [12]: time.strptime("2016-07-05","%Y-%m-%d") #首先自定義一個字符串類型的時間
Out[12]: time.struct_time(tm_year=2016, tm_mon=7, tm_mday=5, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=187, tm_isdst=-1)

In [13]: t_obj = time.strptime("2016-07-05","%Y-%m-%d") #裝換成一個時間對象

In [14]: time.mktime(t_obj)  #最後使用mktime裝換成時間戳
Out[14]: 1467648000.0

In [2]: t_obj = time.gmtime(time.time() - 86400) #時間對象

In [3]: time.strftime("%Y-%m-%d %H:%M:%S")
Out[3]: '2017-10-24 18:42:26'

 - 時間戳與字符串形式之間互相轉換圖

 

 

  - datetime

  

In [1]: import datetime

In [3]: datetime.datetime.now() #返回當前時間(對象)
Out[3]: datetime.datetime(2017, 11, 1, 20, 46, 50, 646785)

In [5]: a = datetime.datetime.now() #將當前時間賦值給一個變量

In [6]: a.date() #取變量中的時間
Out[6]: datetime.date(2017, 11, 1)

In [7]: a.hour #如今是幾點
Out[7]: 20

In [8]: import time

In [9]: datetime.date.fromtimestamp(time.time()) #time.time()是一個時間戳,這裏就是將時間戳直接轉換成時間對象
Out[9]: datetime.date(2017, 11, 1)

In [10]: datetime.datetime.now() + datetime.timedelta(2)
Out[10]: datetime.datetime(2017, 11, 3, 20, 49, 42, 89591)

In [11]: datetime.datetime.now() + datetime.timedelta(minutes=30) #對時間進行加法,這裏是加了30分鐘
Out[11]: datetime.datetime(2017, 11, 1, 21, 20, 8, 957128)

In [14]: time_obj.replace(year=2009) 
Out[14]: datetime.datetime(2009, 11, 1, 20, 50, 44, 210144) #時間替換將年份替換成2009年,其餘不變



"""
    其實經過datetime的使用咱們也不難發現,datetime中存在的方法time模塊中其實都有;我我的觀點就是datetime你只須要會replace和datetime.datetime.now()這兩個方法就好了,在咱們後期的學習中大多數仍是使用time模塊的。
"""

 

  - random模塊

  random模塊是產生隨機字符的一個模塊,這樣明擺着就是打印一個隨機字符串,在應用方面能夠輸出一個驗證碼;

  

random.random() #產生一個隨機的小數
print(random.randint(1,10)) #產生1~10直接任意的一個數,每次執行代碼的時候都會改變
print(random.randrange(1,100,2)) #產生1~10直接的任意一個數不過有間距

a=list(range(10))
print(random.sample(a,2)) #這裏第一個數字必須是傳一個列表或者元組,而後去a的任意兩個數字

  - 使用random隨機產生驗證碼

code = ""
for i in range(4):
    current = random.randrange(0,4)
    if current != i:
        #i == 0~4 current == 0~4 獲取大寫的英文字母
        temp = chr(random.randint(65,90))
    else:
        #i == 0~4 current == 0~4 獲取數字
        temp = random.randint(0,9)
    code += str(temp)

print(code)

 

import random,string

a = string.ascii_letters + string.digits # string.ascii_letters獲取全部的字母,string.digits獲取全部的數字
str_val = random.sample(a,4)
"".join(str_val) 
GDS version

 

  - os模塊

import os

os.getcwd() 獲取當前工做目錄,即當前python腳本工做的目錄路徑
os.chdir("dirname")  改變當前腳本工做目錄;至關於shell下cd
os.curdir  返回當前目錄: ('.')
os.pardir  獲取當前目錄的父目錄字符串名:('..')
os.makedirs('dirname1/dirname2')    可生成多層遞歸目錄
os.removedirs('dirname1')    若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推
os.mkdir('dirname')    生成單級目錄;至關於shell中mkdir dirname
os.rmdir('dirname')    刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname
os.listdir('dirname')    列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印
os.remove()  刪除一個文件
os.rename("oldname","newname")  重命名文件/目錄
os.stat('path/filename')  獲取文件/目錄信息
os.sep    輸出操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/"
os.linesep    輸出當前平臺使用的行終止符,win下爲"\t\n",Linux下爲"\n"
os.pathsep    輸出用於分割文件路徑的字符串
os.name    輸出字符串指示當前使用平臺。win->'nt'; Linux->'posix'
os.system("bash command")  運行shell命令,直接顯示
os.environ  獲取系統環境變量
os.path.abspath(path)  返回path規範化的絕對路徑
os.path.split(path)  將path分割成目錄和文件名二元組返回
os.path.dirname(path)  返回path的目錄。其實就是os.path.split(path)的第一個元素
os.path.basename(path)  返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素
os.path.exists(path)  若是path存在,返回True;若是path不存在,返回False
os.path.isabs(path)  若是path是絕對路徑,返回True
os.path.isfile(path)  若是path是一個存在的文件,返回True。不然返回False
os.path.isdir(path)  若是path是一個存在的目錄,則返回True。不然返回False
os.path.join(path1[, path2[, ...]])  將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略
os.path.getatime(path)  返回path所指向的文件或者目錄的最後存取時間
os.path.getmtime(path)  返回path所指向的文件或者目錄的最後修改時間

  os模塊補充:

  獲取當前路徑的上級路徑:os.path.dirname(os.path.abspath(__file__)) 其中__file__是指運行腳本的絕對路徑

  路徑的拆分:os.path.split(__file__) :拆分後是一個元組

  路徑的拼接(經常使用):os.path.join("C:\\","windows","Python27") -- > C:\windows\Python27

  - sys模塊

#sys 模塊很簡單,咱們只須要記住兩個方法就好了

sys.argv  #命令行參數List,第一個元素是程序自己路徑,第二個就是運行文本後的第一個位置參數
sys.path # 返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值

  - json & pickle 模塊

  - json和pickle都是用來作序列化和反序列化的,而且用法是如出一轍,不一樣的是二者序列化保存到文件的類容和「兼容性」首先pickle保存到文件不是一個明文的,因此看不出任何東西,而json保存到文件是明文並且能看出數據格式;json接口是能夠被任何語言反序列化的,而pickle只能夠被Python程序反序列化,這也致使pickle支持Python中全部的數據類型;(能夠序列化Python中的函數和類,而json不能夠)

  

import json

Leon = {
    "name":"LeonY",
    "age":"18",
    "ha":"CHEN",        
}

#序列化到文件
f = open("filename","w")
f.write(json.dumps(Leon))
f.close

#反序列化到內存
f = open("filename","r")
Leon = json.loads(f)
print(Leon["name"])
f.close()
json寫法

 

import pickle

#序列化保存到文件
Leon = {
    "name":"LeonY",
    "age":"18",
    "ha":"CHEN",
}

f = open("filename","wb")
f.write(pickle.dumps(Leon))
f.close

#反序列化到內存

f = open("filename","rb")
Leon=pickle.loads(f)
print(Leon["name"])
f.close()


#這裏須要注意pickle不論是在dumps或者是loads的時候都是以bytes的方式去讀寫,由於Python3 中默認的加載到硬盤中的字符就是bytes格式的

 

  - logging模塊

  logging模塊是專門在程序運行時打印或者輸出文件日誌的一個模塊;logging模塊中記錄日誌分爲5中級別:debug,info,warning,error,critical,下面咱們看一下logging模塊的最基本使用方法

import logging

#在屏幕上面打印,並顯示日誌級別
logging.info("you're database xxx table info")
logging.critical("you're database is down please paolu")

#輸出至文件中

logging.basicConfig(
    filename="access.log", #日誌文件名
    format="%(levelno)s %(asctime)s %(message)s ", #格式化的字符串也就是日誌中的格式,-詳細信息以下表
    datefmt="%Y-%m-%d %H:%M:%S", #格式化時間格式
    level=logging.INFO, #最低輸出到文件中的日誌級別
)

#向文件中輸出日誌
logging.debug("messge zhongguo haoren ")
logging.info("messge meiguo haoren ")
logging.error("messge hanguo haoren ")
logging.critical("messge riben haoren ")
logging模塊基本使用

 

  日誌格式

%(name)s

Logger的名字

%(levelno)s

數字形式的日誌級別

%(levelname)s

文本形式的日誌級別

%(pathname)s

調用日誌輸出函數的模塊的完整路徑名,可能沒有

%(filename)s

調用日誌輸出函數的模塊的文件名

%(module)s

調用日誌輸出函數的模塊名

%(funcName)s

調用日誌輸出函數的函數名

%(lineno)d

調用日誌輸出函數的語句所在的代碼行

%(created)f

當前時間,用UNIX標準的表示時間的浮 點數表示

%(relativeCreated)d

輸出日誌信息時的,自Logger建立以 來的毫秒數

%(asctime)s

字符串形式的當前時間。默認格式是 「2003-07-08 16:49:45,896」。逗號後面的是毫秒

%(thread)d

線程ID。可能沒有

%(threadName)s

線程名。可能沒有

%(process)d

進程ID。可能沒有

%(message)s

用戶輸出的消息

 

import logging
from logging import handlers

#建立一個文件對象logger
logger = logging.getLogger("TEST-LOG") #TEST-LOG 是輸入到全局中的日誌名稱
logger.setLevel(logging.INFO) #輸出到全局中的日誌等級

# 建立輸出到屏幕上面的log headler
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

#建立輸出到日誌文件的log headler
fh = logging.FileHandler()
fh.setLevel(logging.WARNING)

#建立日誌格式
format_log = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

#將ch和fh格式化輸出

ch.setFormatter(format_log)
fh.setFormatter(format_log)

#將ch和fh將入到logger對象中
logger.addHandler(ch)
logger.addHandler(fh)
更加全面的logging
#一般咱們在輸出到文件日誌,都是須要切割的,因此logging模塊也提供了相對應的接口


import logging
from logging import handlers

#建立一個文件對象logger
logger = logging.getLogger("TEST-LOG") #TEST-LOG 是輸入到全局中的日誌名稱
logger.setLevel(logging.INFO) #輸出到全局中的日誌等級

# 建立輸出到屏幕上面的log headler
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

#建立輸出到日誌文件的log headler
fh = handlers.TimedRotatingFileHandler("access.log",when="S",interval=5,backupCount=3) #按照時間切割,when默認是按照h(小時)來切割,interval是5s切割一次,backupcont是保留幾個,0是無限
#fh = handlers.RotatingFileHandler("access.log",maxBytes=4,backupCount=2)#按照大小切割
fh.setLevel(logging.WARNING)

#建立日誌格式
format_log = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

#將ch和fh格式化輸出

ch.setFormatter(format_log)
fh.setFormatter(format_log)

#將ch和fh將入到logger對象中
logger.addHandler(ch)
logger.addHandler(fh)
功能更增強大的log
相關文章
相關標籤/搜索