Python學習----第二模塊筆記(函數和經常使用模塊)

一、匿名函數

沒有函數名的函數,使用lambda來建立。e.g:node

>>> a = lambda x:x*3
>>> a(3)
9

>>> a = lambda n:print(n)
>>> a("aaa")
aaa

a = map(lambda x: x*2, range(5))
for i in a:
    print(i)
結果:
0
2
4
6
8
#匿名函數與其餘函數搭配使用

二、內置函數

內置函數

abs():返回數字的絕對值python

all():判斷給定的可迭代對象 iterable 中的全部元素是否不爲 0、''、False 或者 iterable 爲空,若是是返回 True,不然返回 False,e.g:git

>>> all([])
True
#空列表
>>> all([0,1,2,3])
False
#0爲False
>>> all([1,2,"",4])
False
#空元素
>>> all([1,2,3,4])
True

any():判斷給定的可迭代對象 iterable 是否所有爲空對象,若是都爲空、0、false,則返回 False,若是不都爲空、0、false,則返回 True,注意與all()的區別,e.g:正則表達式

>>> any([])
False
#空列表
>>> any([0,1,2,3])
True
#一個爲真即爲真
>>> any([1,2,"",4])
True
>>> any([1,2,3,4])
True

ascii():相似 repr() 函數, 返回一個表示對象的字符串, 可是對於字符串中的非 ASCII 字符則返回\x, \u 或 \U 編碼的字符,e.g:算法

>>> a = [1,2,3]
>>> ascii(a)
'[1, 2, 3]'

bin():返回一個整數的二進制,e.g:shell

>>> bin(10)
'0b1010'

bool():將給定參數轉換爲布爾類型,若是沒有參數,返回 False,e.g:json

>>> bool(0)
False
>>> bool(1)
True

bytearray():返回一個新字節數組。這個數組裏的元素是可變的,而且每一個元素的值範圍: 0 <= x < 256,windows

  • 若是傳入參數爲整數,則返回一個長度爲 source 的初始化數組;
  • 若是傳入參數爲字符串,則按照指定的 encoding 將字符串轉換爲字節序列;
  • 若是傳入參數爲可迭代類型,則元素必須爲[0 ,255] 中的整數;
  • 若是傳入參數爲與 buffer 接口一致的對象,則此對象也能夠被用於初始化 bytearray;
  • 若是沒有輸入任何參數,默認就是初始化數組爲0個元素。

e.g:數組

>>> bytearray()
bytearray(b'')
>>> bytearray([1,2,3])
bytearray(b'\x01\x02\x03')
>>> bytearray('a', 'utf-8')
bytearray(b'a')

bytes():返回一個新的 bytes 對象,該對象是一個 0 <= x < 256 區間內的整數不可變序列。它是 bytearray 的不可變版本,e.g:網絡

>>> bytes()
b''
>>> bytes([1,2,3])
b'\x01\x02\x03'
>>> bytes('a','utf-8')
b'a'

callable():檢查一個對象是不是可調用,e.g:

>>> callable(1)
False
>>> def hello():
...     pass
...
>>> callable(hello)
True

chr():返回當前整數對應的ascii字符,e.g:

classmethod:類相關函數,未學

compile():將一個字符串編譯爲字節代碼,語法以下:

compile(source, filename, mode[, flags[, dont_inherit]])

# source -- 字符串或者AST(Abstract Syntax Trees)對象
# filename -- 代碼文件名稱,若是不是從文件讀取代碼則傳遞一些可辨認的值
# mode -- 指定編譯代碼的種類。能夠指定爲 exec, eval, single
# flags -- 變量做用域,局部命名空間,若是被提供,能夠是任何映射對象
# flags和dont_inherit是用來控制編譯源碼時的標誌

e.g:

>>>str = "for i in range(0,5): print(i)" 
>>> c = compile(str,'','exec') 
>>> c
<code object <module> at 0x10141e0b0, file "", line 1>
>>> exec(c)
0
1
2
3
4

complex():建立一個值爲 real + imag * j 的複數或者轉化一個字符串或數爲複數。若是第一個參數爲字符串,則不須要指定第二個參數

delattr():用於刪除屬性,delattr(x,'name') = del x.name

dict():用於建立一個字典,e.g:

>>> dict(a=1,b=2,c=3)
{'a': 1, 'b': 2, 'c': 3}
>>> dict(a='a',b='b')
{'a': 'a', 'b': 'b'}

dir():不帶參數時,返回當前範圍內的變量、方法和定義的類型列表;帶參數時,返回參數的屬性、方法列表。若是參數包含方法__dir__(),該方法將被調用。若是參數不包含__dir__(),該方法將最大限度地收集參數信息,e.g:

>>> dir([])
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

divmod():把除數和餘數運算結果結合起來,返回一個包含商和餘數的元組,e.g:

>>> divmod(10,3)
(3, 1)

enumerate():用於將一個可遍歷的數據對象(如列表、元組或字符串)組合爲一個索引序列,同時列出數據和數據下標,通常用在 for 循環當中,e.g:

>>> for i in enumerate(['a','b','c']):
...     print(i)
...
(0, 'a')
(1, 'b')
(2, 'c')

eval():用來執行一個字符串表達式,並返回表達式的值,e.g:

>>> eval('1+2')
3
>>> eval('[1,2,3]')
[1, 2, 3]

exec():執行儲存在字符串或文件中的 Python 語句,相比於 eval,exec能夠執行更復雜的 Python 代碼,e.g:

>>> exec('for i in range(3):print(i)')
0
1
2

filter():用於過濾序列,過濾掉不符合條件的元素,返回由符合條件元素組成的新列表。該函數接收兩個參數,第一個爲函數,第二個爲可迭代對象,可迭代對象的每一個元素做爲參數傳遞給函數進行判,而後返回 True 或 False,最後將返回 True 的元素放到新列表中,e.g:

def is_odd(n):
    return n % 2 == 1
for i in filter(is_odd, range(10)):
    print(i)
結果:
1
3
5
7
9

float():用於將整數和字符串轉換成浮點數

format():用於字符串的格式化輸出,e.g:

name = "Python"
age = 28
print("{}的年齡爲{}".format(name, age))
結果:
Python的年齡爲28

frozenset():返回一個凍結的集合,凍結後集合不能再添加或刪除任何元素

getattr():用於返回一個對象屬性值

getattr(object, name[, default])
#object -- 對象
#name -- 字符串,對象屬性
#default -- 默認返回值,若是不提供該參數,在沒有對應屬性時,將觸發 AttributeError

globals():以字典類型返回當前位置的所有全局變量

hasattr():用於判斷對象是否包含對應的屬性,e.g:

>>> hasattr([],'append')
True
>>> hasattr([],'isdigit')
False

hash():獲取取一個對象(字符串或者數值等)的哈希值,e.g:

>>> hash('a')
7807180544025395620

help():用於查看函數或模塊用途的詳細說明

hex():用於將10進制整數轉換成16進制整數,e.g:

>>> hex(10)
'0xa'

id():用於獲取對象的內存地址

input():用於獲取控制檯輸入

int():將字符串數字轉換爲整型

isinstance():判斷一個對象是不是一個已知的類型,e.g:

>>> isinstance(a,int)
True
>>> isinstance(a,str)
False
>>> isinstance(a,(int,str,list))
True
#是元組中的一個是返回True

issubclass():用於判斷是不是子類

iter():用於生成迭代器

len():返回對象(字符、列表、元組等)長度或項目個數

list():將元組轉換爲列表

locals():以字典類型返回當前位置的所有局部變量

map():接收一個函數和一個列表,並經過把函數依次做用在列表的每一個元素上,獲得一個新的列表並返回,e.g:

>>> a = map(lambda x:x*2,range(5))
>>> for i in a:
...     print(i)
...
0
2
4
6
8

max():返回給定參數的最大值

memoryview():返回給定參數的內存查看對象(Momory view)。所謂內存查看對象,是指對支持緩衝區協議的數據進行包裝,在不須要複製對象基礎上容許Python代碼訪問

min():返回給定參數的最小值

next():返回可迭代對象的下一個值

oct():將一個整數轉換成八進制

open():打開文件

ord():chr()函數的反函數

pow():返回 xy(x的y次方) 的值,e.g:

>>> pow(1,2)
1

print():打印輸出

property() :在新式類中返回屬性值

range():建立整數列表

repr():將對象轉化爲供解釋器讀取的字符串形式,e.g:

>>> a = {'a':1,'b':2}
>>> repr(a)
"{'a': 1, 'b': 2}"

reversed():反轉可迭代對象,e.g:

>>> a = [1,2,3]
>>> list(reversed(a))
[3, 2, 1]

round():返回浮點數的四捨五入值

set():建立一個集合

setattr():對應函數getatt()用於設置屬性值,該屬性必須存在

slice():實現切片對象,主要用在切片操做函數裏的參數傳遞,e.g:

>>> a = [1,2,3,4,5]
>>> myslice = slice(2)
>>> a[myslice]
[1, 2]

sorted():對可迭代對象排序

staticmethod():返回函數的靜態方法

str():將對象轉換成始於人閱讀的字符串形式

sum():對可迭代對象求和,e.g:

>>> sum([1,2,3])
6

super():函數用於調用下一個父類(超類)並返回該父類實例的方法。super 是用來解決多重繼承問題的,直接用類名調用父類方法在使用單繼承的時候沒問題,可是若是使用多繼承,會涉及到查找順序(MRO)、重複調用(鑽石繼承)等種種問題。MRO 就是類的方法解析順序表, 其實也就是繼承父類方法時的順序表

tuple():將列表轉換成元組

type():返回對象的數據類型,e.g:

>>> type(1)
<class 'int'>
>>> type('1')
<class 'str'>

vars():返回對象的屬性和屬性值的字典對象

zip():用於將可迭代的對象做爲參數,將對象中對應的元素打包成一個個元組,而後返回由這些元組組成的列表。若是各個迭代器的元素個數不一致,則返回列表長度與最短的對象相同,利用 * 號操做符,能夠將元組解壓爲列表,e.g:

>>> a = [1,2,3]
>>> b = [4,5,6]
>>> list(zip(a,b))
[(1, 4), (2, 5), (3, 6)]

__import__():用於動態加載類和函數 。若是一個模塊常常變化就可使用 __import__() 來動態載入

三、裝飾器

decorator,本質上是一個函數,用於裝飾其餘函數,爲其餘函數添加新的功能。

裝飾器須要遵循如下原則:

  • 不能修改被裝飾函數的源代碼
  • 不能修改被裝飾函數的調用方式

裝飾器須要知識:

  • 函數即「變量」,函數名 = 函數體,必須先聲明再調用
  • 高階函數,知足如下條件之一 

               a.把一個函數名看成實參傳給另外一個函數(實如今不修改被裝飾函數源代碼的狀況下爲其添加新功能)

               b.返回值中包含函數(實現不修改函數的調用方式)

  • 嵌套函數,在一個函數的函數體內用def聲明一個新的函數
  • 閉包,在一個內部函數裏,對在外部做用域(不是全局做用域)的變量進行引用,這個內部函數就是閉包(closure)

裝飾器 = 高階函數+嵌套函數+閉包

def test():
    print("測試函數!")

print(test)
print(test())

#結果(注意調用函數帶括號與不帶括號時的區別)
<function test at 0x000001D23579AEA0>    # 不帶括號指向函數的內存地址
測試函數!    # 帶括號執行函數
None    # 函數的返回值,無return語句返回None

e.g:

#函數帶一個參數例子
#未加裝飾器
def test1(name):
    print("你的名字%s" % name)

test1("Python")
#結果
你的名字Python

#加上裝飾器
def deco(func):
    def test(x):
        print("裝飾器例子。")
        func(x)
        print("結束。")
    return test


@deco
def test1(name):
    print("你的名字%s" % name)

test1("Python")
#結果
裝飾器例子。
你的名字Python
結束。
#函數帶多個參數
def deco(func):
    def test(*args, **kwargs):
        print("裝飾器例子。")
        func(*args, **kwargs)
        print("結束。")
    return test


@deco
def test1(name, age):
    print("你的名字%s,你的年齡%s" % (name, age))

test1("Python", 28)
#結果
裝飾器例子。
你的名字Python,你的年齡28
結束。
#帶參數的裝飾器
def deco(x):
    def test(func):
        def test1(*args, **kwargs):
            print("裝飾器例子。")
            func(*args, **kwargs)
            print("結束。看看帶參數的裝飾器%s" % x)
        return test1
    return test


@deco(1)
def test2(name, age):
    print("你的名字%s,你的年齡%s" % (name, age))

test2("Python", 28)
#結果
裝飾器例子。
你的名字Python,你的年齡28
結束。看看帶參數的裝飾器1
def login(func):
    def deco(*args, **kwargs):
        func(*args, **kwargs)
        name, pw = "abc", "abc123"
        username = input("請輸入用戶名-->")
        password = input("請輸入密碼-->")
        if username == name and password == pw:
            print("歡迎%s回來!" % username)
        else:
            print("用戶名或密碼錯誤!")
    return deco


def welcome():
    print("歡迎你的到來!")


@login
def user():
    print("請登陸-->")

welcome()

user()
#結果
歡迎你的到來!
請登陸-->
請輸入用戶名-->abc
請輸入密碼-->abc123
歡迎abc回來!

四、列表生成式

生成列表,可使代碼更整潔,e.g:

>>> a = [i*2 for i in range(5)]
>>> a
[0, 2, 4, 6, 8]
#生成一個列表,列表成員爲0-4依次乘於2

五、生成器

受內存限制,列表的容量有限,建立大量元素的列表須要的存儲空間巨大,並且列表的元素是固定存在的,若是隻訪問前面的元素,那麼後面的元素佔用的空間就浪費了。

生成器generator,一邊循環一邊計算的機制,只在調用時才生成相應的數據,只記住當前值,沒法返回前面的值,只能下一個,將列表生成式的[]換成()就能夠建立一個生成器,e.g:

>>> a = (i*2 for i in range(5))
>>> next(a)
0
>>> next(a)
2
>>> next(a)
4
#使用next()函數調用下一個值
>>> for i in a:
...     print(i)
...
6
8
#經過for循環調用,注意輸出結果,由於已經使用next()函數調用了三個值,因此for循環只輸出了最後兩個值

#另一種next使用方法
>>> a = (i*2 for i in range(5))
>>> a.__next__()
0
>>> a.__next__()
2
>>> a.__next__()
4
#使用函數建立生成器

#原函數
def test():
    for i in range(4):
        print(i)
        
test()
#結果
0
1
2
3

#建立生成器
def test():
    for i in range(4):
        yield i

data = test()

print(next(data))
print(next(data))
print(next(data))
print(next(data))
#結果
0
1
2
3
#生成器並行運算

def test(name):
    while True:
        yield
        print("他的名字是%s" % name)


def test1(name):
    a = test("JAVA")
    a.__next__()
    for i in range(3):
        print("個人名字是%s" % name)
        a.send(i)     # 回到上次yield中斷的地方

test1("Python")
#結果
個人名字是Python
他的名字是JAVA
個人名字是Python
他的名字是JAVA
個人名字是Python
他的名字是JAVA

六、迭代器

可迭代對象(Iterable):因此能夠直接做用於for循環的對象,如列表、字典、生成器等

迭代器(Iterator):能夠被next()函數調用並不斷返回下一個值的對象,惰性計算序列,只有在須要返回值的時候才進行計算

#可使用isinstance()函數判斷是不是可迭代對象或者迭代器

#可使用for循環的都是可迭代對象
>>> from collections import Iterable
>>> isinstance([],Iterable)
True
>>> isinstance({},Iterable)
True
>>> isinstance((i*2 for i in range(5)),Iterable)
True

#列表、字典沒法使用next()函數,因此不是迭代器
>>> from collections import Iterator
>>> isinstance([],Iterator)
False
>>> isinstance({},Iterator)
False

#生成器可使用next()函數,因此是迭代器
>>> isinstance((i*2 for i in range(5)),Iterator)
True
#使用iter()函數能夠把一個可迭代對象轉換成迭代器
>>> from collections import Iterator
>>> isinstance(iter([]),Iterator)
True

七、軟件目錄開發規範

Foo/
|-- bin/    #存放項目的一些可執行文件
|   |-- foo.py    #程序執行文件,調用main.py文件實現各類功能
|
|-- foo/    #存放項目的全部源代碼(1) 源代碼中的全部模塊、包都應該放在此目錄,不要置於頂層目錄;(2) 其子目錄tests/存放單元測試代碼; (3) 程序的入口最好命名爲main.py。
|   |-- tests/
|   |   |-- __init__.py
|   |   |-- test_main.py
|   |
|   |-- __init__.py
|   |-- main.py    #程序的主入口,負責調用其餘模塊
|
|-- docs/       #存放一些文檔
|
|-- conf/    #存放配置文件
|   |--conf.py
|
|-- setup.py    #安裝、部署、打包的腳本
|-- requirements.txt    #存放軟件依賴的外部Python包列表
|-- README

八、Python模塊及import的本質

模塊在本質上是.py文件,用來從邏輯上組織python代碼,以實現某個功能

包在本質上是一個帶有__init__.py文件的目錄,用來從邏輯上組織模塊。導入包的本質即解釋目錄下的__init__.py文件。

模塊的導入方法

import xxx

from xxx import xxx

from xxx import xxx as xxx
#as能夠將原模塊名在導入的時候定義一個新名稱

import在本質上就是把import的模塊中的代碼解釋一遍並賦值給模塊名

模塊的分類:

  • 標準庫(內置模塊)
  • 開源模塊(第三方模塊)
  • 自定義模塊(本身寫的模塊)
#不一樣目錄間模塊調用
#使用os,sys模塊的功能
#目錄結構以下
|--a/
|  |--aa/
|     |--aaa.py
|
|  |--bb/
|     |--bbb.py
#在aaa.py中須要調用bbb.py

os.path.abspath(__file__)    #返回當前文件的絕對路徑,在這裏爲a/aa/aaa.py
os.path.dirname()   #返回當前文件所在的目錄
os.path.dirname(os.path.abspath(__file__))   #這裏爲a/aa
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))    #這裏爲a,已經能夠找到bb了
sys.path.append()    #將路徑加入python搜索模塊的路徑列表中

#代碼以下
import os
import sys
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
from bb import bbb
bbb.xxx()#調用bbb下的xxx方法

九、Python標準庫(內置模塊)

9.一、time和date time模塊

Python中表示時間的方式:

  • 時間戳,表示從1970年1月1日00:00:00開始按秒計算的偏移量
  • 格式化的時間字符串
  • 元組(struct_time),共九個元素

UTC(世界協調時),格林威治時間,世界標準時間。中國位於東八區,即UTC+8

import time

#time.process_time()(time.clock()) 測量處理器運算時間,不包括sleep的時間,e.g:
>>> time.process_time()
0.109375

#time.time() 返回當前時間戳,e.g:
>>> time.time()
1508682933.4166296

#time.altzone 返回格林威治西部的夏令時地區的偏移秒數,若是該地區在格林威治東部會返回負值(如西歐,包括英國),對夏令時啓用地區才能使用,e.g:
>>> time.altzone
-32400

#time.asctime() 接受struct_time並返回時間格式「Sun Oct 22 22:40:53 2017」,e.g:
>>> time.asctime(time.localtime())
'Sun Oct 22 22:43:34 2017'

#time.localtime() 返回本地時間的struct_time,e.g:
>>> time.localtime()
time.struct_time(tm_year=2017, tm_mon=10, tm_mday=22, tm_hour=22, tm_min=45, tm_sec=48, tm_wday=6, tm_yday=295, tm_isdst=0)

#time.gmtime() 返回UTC時間的struct_time,e.g:
>>> time.gmtime()
time.struct_time(tm_year=2017, tm_mon=10, tm_mday=22, tm_hour=14, tm_min=47, tm_sec=12, tm_wday=6, tm_yday=295, tm_isdst=0)

#time.ctime() 同time.asctime(),e.g:
>>> time.ctime()
'Sun Oct 22 22:49:55 2017'

#time.strptime 將日期字符串轉成struct_time,e.g:
>>> time.strptime("2017/01/22","%Y/%m/%d")
time.struct_time(tm_year=2017, tm_mon=1, tm_mday=22, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=22, tm_isdst=-1)

#time.mktime() 將struct_time轉成時間戳,e.g:
>>> time.mktime(time.localtime())
1508684200.0

#time.strftime() 將struct_time轉成指定的字符串格式,e.g:
>>> time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
'2017-10-22 22:59:33'
#格式:
# %a    本地(locale)簡化星期名稱    
# %A    本地完整星期名稱    
# %b    本地簡化月份名稱    
# %B    本地完整月份名稱    
# %c    本地相應的日期和時間表示    
# %d    一個月中的第幾天(01 - 31)    
# %H   一天中的第幾個小時(24小時制,00 - 23)    
# %I     第幾個小時(12小時制,01 - 12)    
# %j     一年中的第幾天(001 - 366)    
# %m   月份(01 - 12)    
# %M   分鐘數(00 - 59)    
# %p    本地am或者pm的相應符
# %S    秒(01 - 61)
# %U    一年中的星期數。(00 - 53星期天是一個星期的開始。)第一個星期天以前的全部天數都放在第0周。
# %w    一個星期中的第幾天(0 - 6,0是星期天)
# %W   和%U基本相同,不一樣的是%W以星期一爲一個星期的開始。    
# %x     本地相應日期    
# %X    本地相應時間    
# %y     去掉世紀的年份(00 - 99)    
# %Y    完整的年份    
# %Z    時區的名字(若是不存在爲空字符)    
# %%    ‘%’字符
#時間加減
import datetime

#datetime.datetime.now() 
>>> print(datetime.datetime.now())
2017-10-22 23:13:54.766792

#datetime.date.fromtimestamp() 時間戳直接轉成日期格式
>>>>>> print(datetime.date.fromtimestamp(time.time()))
2017-10-22

#當前時間+3天
>>> print(datetime.datetime.now() + datetime.timedelta(3))
2017-10-25 23:14:43.124703

#當前時間-3天
>>> print(datetime.datetime.now() + datetime.timedelta(-3))
2017-10-19 23:15:31.525936

#當前時間+3小時
>>> print(datetime.datetime.now() + datetime.timedelta(hours=3))
2017-10-23 02:17:01.242468

#當前時間+30分鐘
>>> print(datetime.datetime.now() + datetime.timedelta(minutes=30))
2017-10-22 23:47:34.411346

#時間替換
>>> c_time  = datetime.datetime.now()
>>> print(c_time)
2017-10-22 23:19:10.420363
>>> print(c_time.replace(minute=3,hour=2))
2017-10-22 02:03:10.420363

time

9.二、random模塊

用於生成一個隨機數

import random

#random.random() 生成一個0到1的隨機浮點數,e.g:
>>> random.random()
0.11953524555173556
>>> random.random()
0.43441252324763446
>>> random.random()
0.2674464150139263

#random.randint() 生成一個指定範圍的隨機整數,e.g:
>>> random.randint(2,9)
8
>>> random.randint(2,9)
3
>>> random.randint(2,9)
8

#random.randrange() 從指定範圍內,按指定基數遞增的集合中獲取一個隨機數,e.g:
>>> random.randrange(0,20,2)
4
>>> random.randrange(0,20,2)
2
>>> random.randrange(0,20,2)
12

#random.choice() 從序列中獲取一個隨機元素,e.g:
>>> random.choice("I am Python")
'I'
>>> random.choice("I am Python")
' '
>>> random.choice("I am Python")
'y'
>>> random.choice([1,3,5,7,9])
5
>>> random.choice([1,3,5,7,9])
7
>>> random.choice([1,3,5,7,9])
3

#random.sample() 從指定序列中隨機獲取指定長度的片斷,e.g:
>>> random.sample([1,3,5,7,9,11,13,15,17,19],3)
[7, 19, 15]
>>> random.sample([1,3,5,7,9,11,13,15,17,19],3)
[9, 7, 15]
>>> random.sample([1,3,5,7,9,11,13,15,17,19],3)
[11, 9, 3]

9.三、os模塊和sys模塊

#os模塊
import os

#os.getcwd() 獲取當前工做目錄,即當前python腳本工做的目錄路徑,e.g:
>>> os.getcwd()
'C:\\Users\\MAIMAI'

#os.chdir() 改變當前腳本工做目錄,e.g:
>>> os.chdir(r"d:")
>>> os.getcwd()
'D:\\'

#os.curdir 返回當前目錄: ('.'),e.g:
>>> os.curdir
'.'

#os.pardir  獲取當前目錄的父目錄字符串名:('..'),e.g:
>>> os.pardir
'..'

#os.makedirs() 可生成多層遞歸目錄,e.g:
>>> os.makedirs(r"d:\a\b\c")

#os.removedirs() 若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推

#os.mkdir() 生成單級目錄,e.g:
>>> os.mkdir(r"d:\d")
>>> os.mkdir(r"d:\f\d")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [WinError 3] 系統找不到指定的路徑。: 'd:\\f\\d'    # 只能生成單級目錄,上級目錄不存在時報錯

#os.rmdir() 刪除單級空目錄,若目錄不爲空則沒法刪除,報錯

#os.listdir() 列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印,e.g:
>>> os.listdir(r"d:\a")
['b', 'c', 'd']

#os.remove() 刪除一個文件

#os.rename() 重命名文件/目錄,e.g:
>>> os.listdir(r"d:\a")
['b', 'c', 'd']
>>> os.rename(r"d:\a\b",r"d:\a\e")
>>> os.listdir(r"d:\a")
['c', 'd', 'e']

#os.stat() 獲取文件/目錄信息,e.g:
>>> os.stat(r"d:\a")
os.stat_result(st_mode=16895, st_ino=11821949021849245, st_dev=520988, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1508687570, st_mtime=1508687570, st_ctime=1508687154)

#os.sep 輸出操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/"

#os.linesep 輸出當前平臺使用的行終止符,win下爲"\t\n",Linux下爲"\n"

#os.pathsep 輸出用於分割文件路徑的字符串

#os.name 輸出字符串指示當前使用平臺。win->'nt'; Linux->'posix'

#os.system() 運行shell命令,直接顯示,e.g:
>>> os.system("ping www.baidu.com")

正在 Ping www.a.shifen.com [183.232.231.173] 具備 32 字節的數據:
來自 183.232.231.173 的回覆: 字節=32 時間=23ms TTL=52
來自 183.232.231.173 的回覆: 字節=32 時間=22ms TTL=52
來自 183.232.231.173 的回覆: 字節=32 時間=21ms TTL=52
來自 183.232.231.173 的回覆: 字節=32 時間=24ms TTL=52

183.232.231.173 的 Ping 統計信息:
    數據包: 已發送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計時間(以毫秒爲單位):
    最短 = 21ms,最長 = 24ms,平均 = 22ms
0

#os.environ 獲取系統環境變量

#os.path.abspath() 返回規範化的絕對路徑

#os.path.split() 將路徑分割成目錄和文件名二元組返回,e.g:
>>> os.path.split(r"d:\a")
('d:\\', 'a')

#os.path.dirname() 返回文件所在的目錄,其實就是os.path.split()的第一個元素

#os.path.basename() 返回目錄/文件最後的名稱,如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素,e.g:
>>> os.path.basename(r"d:\a")
'a'

#os.path.exists() 存在,返回True;不存在,返回False,e.g:
>>> os.path.exists(r"d:\a")
True

#os.path.isabs() 若是是絕對路徑,返回True,e.g:
>>> os.path.isabs(r"d:\a")
True

#os.path.isfile()  若是是一個存在的文件,返回True,不然返回False,e.g:
>>> os.path.isfile(r"d:\a")
False
>>> os.path.isfile(r"d:\a\a.txt")
True

#os.path.isdir() 若是是一個存在的目錄,則返回True,不然返回False,e.g:
>>> os.path.isdir(r"d:\a")
True

#os.path.join() 將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略,e.g:
>>> os.path.join(r"d:",r"\a",r"b",r"c")
'd:\\a\\b\\c'

#os.path.getatime() 返回所指向的文件或者目錄的最後存取時間

#os.path.getmtime() 返回所指向的文件或者目錄的最後修改時間

os模塊補充

#os.walk() os.walk() 方法用於經過在目錄樹種遊走輸出在目錄中的文件名,向上或者向下。
#os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])
#top -- 根目錄下的每個文件夾(包含它本身), 產生3-元組 (dirpath, dirnames, filenames)【文件夾路徑, 文件夾名字[列表], 文件名[列表]】。
#topdown --可選,爲True或者沒有指定, 一個目錄的的3-元組將比它的任何子文件夾的3-元組先產生 (目錄自上而下)。若是topdown爲 False, 一個目錄的3-元組將比它的任何子文件夾的3-元組後產生 (目錄自下而上)。
#onerror -- 可選,是一個函數; 它調用時有一個參數, 一個OSError實例。報告這錯誤後,繼續walk,或者拋出exception終止walk。
#followlinks -- 設置爲 true,則經過軟連接訪問目錄。
#e.g:
for dirpath, dirname, filename in os.walk(r"f:"):
    print(dirpath, dirname, filename)
sys模塊

import sys

#sys.argv 命令行參數List,第一個元素是程序自己路徑,e.g:
import sys
print(sys.argv[1:])
--->test.py
f:\python>python test.py 1 2 3
['1', '2', '3']

#sys.exit() 引起一個 SystemExit異常,若沒有捕獲這個異常,Python解釋器會直接退出,捕獲這個異常能夠作一些額外的清理工做。0爲正常退出,其餘數值(1-127)爲不正常,可拋異常事件供捕獲

#sys.version 獲取Python解釋器的版本信息
>>> sys.version
'3.6.2 (v3.6.2:5fd33b5, Jul  8 2017, 04:57:36) [MSC v.1900 64 bit (AMD64)]'

#sys.path 返回列表形式的模塊的搜索路徑,

#sys.platform 返回操做系統的名稱

#sys.stdout.write 輸出,相似print

9.四、shutil模塊

高級的文件、文件夾、壓縮包處理模塊

import shutil

#shutil.copyfileobj(fsrc, fdst[, length]) 將文件內容拷貝到另外一個文件中,能夠部份內容,須要先用open打開文件

#shutil.copyfile(src, dst) 拷貝文件,不用先open

#shutil.copymode(src, dst) 僅拷貝權限,內容、組、用戶均不變

#shutil.copystat(src, dst) 拷貝狀態的信息,包括權限、組、用戶、時間等

#shutil.copy(src, dst) 拷貝文件和僅權限

#shutil.copy2(src, dst) 拷貝文件和文件的全部狀態信息

#shutil.ignore_patterns(*patterns)
#shutil.copytree(src, dst, symlinks=False, ignore=None) 遞歸的去拷貝文件
#e.g:copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))

#shutil.rmtree(path[, ignore_errors[, onerror]]) 遞歸的去刪除文件

#shutil.move(src, dst) 遞歸的去移動文件

#shutil.make_archive(base_name, format,...) 建立壓縮包並返回文件路徑
# base_name: 壓縮包的文件名,也能夠是壓縮包的路徑。只是文件名時,則保存至當前目錄,不然保存至指定路徑
#  format: 壓縮包種類,「zip」, 「tar」, 「bztar」,「gztar」
#  root_dir: 要壓縮的文件夾路徑(默認當前目錄)
#  owner: 用戶,默認當前用戶
#  group: 組,默認當前組
# logger: 用於記錄日誌,一般是logging.Logger對象

9.五、json、pickle和shelve模塊

json模塊用來編碼和解碼JSON對象,只支持簡單的數據類型,如列表、字典等

import json

#json.dumps 將Python對象編碼成JSON字符串
#json.loads 將JSON字符串解碼成Python對象

#json.dump 將Python對象編碼成JSON字符串並寫入文件
#json.load 從文件中讀取JSON字符串並解碼成Python對象

#json只支持簡單的數據類型,如列表、字典等

pickle模塊用於python特有的類型和python的數據類型間進行轉換,可序列化python全部數據類型

import pickle

#pickle.dumps 序列化
#pickle.loads 反序列化

#pickle.dump 寫入文件
#pickle.load 從文件中讀取

#存儲的是二進制文件,open文件時應該使用rb、wb、ab模式

shelve模塊經過鍵值對的形式對內存數據進行文件持久化的模塊,能夠持久化任何pickle可支持的python數據格式,e.g:

import shelve

a = [1, 2, 3]

f = shelve.open("test")
f["test"] = a
f.close()
#將列表持久化保存
f1 = shelve.open("test")
print(f1["test"])
f1.close()
#經過鍵從文件中讀取列表

#結果
[1, 2, 3]

9.六、xml處理模塊

用於處理xml文件,需導入xml.etree.ElementTree模塊。

#如下是一個xml文件的內容

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>
#xml文件的讀取

import xml.etree.ElementTree as xml_ET  # 模塊名太長,改個名

tree = xml_ET.parse("test.xml")
root = tree.getroot()   # <data></data>包起來的內容
print(root.tag)    # 打印root標籤

#結果
data
import xml.etree.ElementTree as xml_ET  # 模塊名太長,改個名

tree = xml_ET.parse("test.xml")
root = tree.getroot()   # <data></data>包起來的內容

for child in root:    # 遍歷整個xml文件
    print(child.tag, child.attrib)    #讀取標籤及屬性

#結果
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}

import xml.etree.ElementTree as xml_ET  # 模塊名太長,改個名

tree = xml_ET.parse("test.xml")
root = tree.getroot()   # <data></data>包起來的內容

for child in root:    # 遍歷整個xml文件
    for i in child:    # 遍歷<country></country>包起來的內容
        print(i.tag, i.text)    # 讀取標籤及標籤包起來的內容

#結果
rank 2
year 2008
gdppc 141100
neighbor None
neighbor None
rank 5
year 2011
gdppc 59900
neighbor None
rank 69
year 2011
gdppc 13600
neighbor None
neighbor None

import xml.etree.ElementTree as xml_ET  # 模塊名太長,改個名

tree = xml_ET.parse("test.xml")
root = tree.getroot()   # <data></data>包起來的內容

for node in root.iter("year"):  # 只遍歷year節點
    print(node.tag, node.text)     # 打印標籤及標籤包起來的內容

#結果
year 2008
year 2011
year 2011
#xml文件的修改

import xml.etree.ElementTree as xml_ET

tree = xml_ET.parse("test.xml")
root = tree.getroot()

for node in root.iter("year"):    # 修改year節點
    new_year = int(node.text) + 1
    node.text = str(new_year)
    node.set("updated", "yes")    # <year>標籤修改爲<year updated="yes">

tree.write("test.xml")    # 修改內容寫入xml文件

# 刪除node
for country in root.findall("country"):
    rank = int(country.find("rank").text)   # 讀取<rank></rank>中的內容
    if rank > 50:
        root.remove(country)    # 刪除符合條件的country

tree.write("output.xml")
#建立xml文件

import xml.etree.ElementTree as xml_ET

new_xml = xml_ET.Element("namelist")    # 大標籤
name = xml_ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"})   # 大標籤下的子標籤及子標籤屬性
age = xml_ET.SubElement(name, "age", attrib={"checked": "no"})
sex = xml_ET.SubElement(name, "sex")
sex.text = '33'   # <sex>中的內容
name2 = xml_ET.SubElement(new_xml, "name", attrib={"enrolled": "no"})
age = xml_ET.SubElement(name2, "age")
age.text = '19'

et = xml_ET.ElementTree(new_xml)  # 生成文檔對象
et.write("test1.xml", encoding="utf-8", xml_declaration=True)   # 寫入文件並打上xml標誌

xml_ET.dump(new_xml)  # 打印生成的格式

9.七、PyYAML和configparser模塊

PyYAML模塊用來處理ymal文檔格式,具體用法參照http://pyyaml.org/wiki/PyYAMLDocumentation 

configparser模塊用於建立和修改經常使用的配置文件。

#如下是一個配置文件的內容

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes
 
[bitbucket.org]
User = hg
 
[topsecret.server.com]
Port = 50022
ForwardX11 = no
#建立配置文件

import configparser

config = configparser.ConfigParser()

config["DEFAULT"] = {'ServerAliveInterval': '45',
                     'Compression': 'yes',
                     'CompressionLevel': '9'}

config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'

config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022'
topsecret['ForwardX11'] = 'no'
config['DEFAULT']['ForwardX11'] = 'yes'
with open('example.ini', 'w') as configfile:
    config.write(configfile)
# 實質上就是對字典的操做
#讀取配置文件

import configparser

config = configparser.ConfigParser()
print(config.read("example.ini"))
print(config.sections())
print(config.options("bitbucket.org"))
print(config.items("bitbucket.org"))    # 輸出列表形式的鍵值對
print(config.get("bitbucket.org", "compression"))   # 輸出字符串
print(config.getint("bitbucket.org", "compressionlevel"))   # 輸出int
print(config["bitbucket.org"]["user"])

#結果
['example.ini']
['bitbucket.org', 'topsecret.server.com']
['user', 'serveraliveinterval', 'compression', 'compressionlevel', 'forwardx11']
[('serveraliveinterval', '45'), ('compression', 'yes'), ('compressionlevel', '9'), ('forwardx11', 'yes'), ('user', 'hg')]
yes
9
hg
#修改配置文件

import configparser

config = configparser.ConfigParser()
config.read("example.ini")    # 必須先讀取配置文件

config.add_section("baidu.com")    # 新建

config.set("topsecret.server.com", "forwardx11", "yes")    # 修改

config.remove_option("topsecret.server.com", "Port")   # 刪除

config.remove_section("topsecret.server.com")

config.write(open("example.ini", "w"))    # 修改內容寫入配置文件

#檢查一個section是否存在
import configparser

config = configparser.ConfigParser()
config.read("example.ini")

print(config.has_section("baidu.com"))

#結果
True

9.八、hashlib模塊

用於加密的模塊,提供了SHA1,SHA224,SHA256,SHA384,SHA512,MD5 算法,e.g:

import hashlib

m_b = hashlib.md5()
m_b.update(b"I am Python")    # 直接傳入字符串報錯,需轉編碼
print(m_b.hexdigest())    # 十六進制輸出
m_utf8 = hashlib.md5()
m_utf8.update("I am Python".encode("utf-8"))    # 轉utf-8
print(m_utf8.hexdigest())

b = hashlib.sha1()
b.update(b"I am Python")
print(b.hexdigest())

zh_cn = hashlib.md5()
zh_cn.update("我是Python".encode("utf-8"))    # 中文直接傳utf-8
print(zh_cn.hexdigest())

#結果
563f710d7f1020c8ee1c95f77650918a
563f710d7f1020c8ee1c95f77650918a
a1780aaa27454ce0a9ee7a7518405d8c72523843
c46b544b85b64a0a45c6081e2fbacbaf

hmac模塊可對自定義的key和內容進行處理後再加密,e.g:

import hmac

a = hmac.new("我是Python".encode("utf-8"), "我是Python2".encode("utf-8"))
print(a.hexdigest())

#結果
deb7cd3a5ac6169c841fdaaf8b10f384

9.九、logging模塊

logging模塊提供標準的日誌接口,可存儲各類格式的日誌,logging的日誌分爲debug、info、warning、error、critical五個級別 ,

  • DEBUG:詳細的信息,一般只出如今診斷問題上
  • INFO:確認一切按預期運行
  • WARNING:一個跡象代表,一些意想不到的事情發生了,或代表一些問題在不久的未來(例如。磁盤空間低」)。這個軟件還能按預期工做。
  • ERROR:更嚴重的問題,軟件沒能執行一些功能
  • CRITICAL:一個嚴重的錯誤,這代表程序自己可能沒法繼續運行
import logging

logging.debug("debug")
logging.info("info")
logging.warning("warning")
logging.error("error")
logging.critical("critical")

#結果
WARNING:root:warning
ERROR:root:error
CRITICAL:root:critical
#報警按級別顯示,debug、info默認不顯示

logging.basicConfig(filename='test.log',level=logging.INFO) 
#將日誌寫入文件,level定義記錄的日誌級別,低於該級別的日誌不被記錄

logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
#爲日誌加上一些格式

#日誌格式具體以下
# %(name)s               Logger的名字
# %(levelno)s            數字形式的日誌級別
# %(levelname)s          文本形式的日誌級別
# %(pathname)s           調用日誌輸出函數的模塊的完整路徑名,可能沒有
# %(filename)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            用戶輸出的消息

Python 使用logging模塊記錄日誌涉及四個主要類:

  • logger提供了應用程序能夠直接使用的接口
  • handler將(logger建立的)日誌記錄發送到合適的目的輸出
  • filter提供了細度設備來決定輸出哪條日誌記錄
  • formatter決定日誌記錄的最終輸出格式
logger

每一個程序在輸出信息以前都要得到一個Logger,Logger一般對應了程序的模塊名

logging.getLogger():得到一個Logger

Logger.setLevel():指定最低的日誌級別,低於設置的級別將被忽略

Logger.addFilter()、Logger.removeFilter():添加或刪除指定的filter

Logger.addHandler()、Logger.removeHandler():增長或刪除指定的handler

Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():能夠設置的日誌級別

handler

handler對象負責發送相關的信息到指定目的地。Python的日誌系統有多種Handler可使用。有些Handler能夠把信息輸出到控制檯,有些Handler能夠把信息輸出到文件,還有些 Handler能夠把信息發送到網絡上。若是以爲不夠用,還能夠編寫本身的Handler。能夠經過addHandler()方法添加多個多handler

Handler.setLevel():指定被處理的信息級別,低於設置級別的信息將被忽略
Handler.setFormatter():給這個handler選擇一個格式
Handler.addFilter()、Handler.removeFilter():新增或刪除一個filter對象

經常使用Handler:

一、logging.StreamHandler,使用這個Handler能夠向相似與sys.stdout或者sys.stderr的任何文件對象(file object)輸出信息。它的構造函數是:StreamHandler([strm]),其中strm參數是一個文件對象。默認是sys.stderr。

二、logging.FileHandler,和StreamHandler相似,用於向一個文件輸出日誌信息。FileHandler會幫你打開這個文件。它的構造函數是:FileHandler(filename[,mode]),filename是文件名,必須指定一個文件名。mode是文件的打開方式,默認是「a」,即添加到文件末尾。

三、logging.handlers.RotatingFileHandler,這個Handler相似於上面的FileHandler,可是它能夠管理文件大小。當文件達到必定大小以後,它會自動將當前日誌文件更名,而後建立一個新的同名日誌文件繼續輸出。好比日誌文件是chat.log。當chat.log達到指定的大小以後,RotatingFileHandler自動把文件更名爲chat.log.1。不過,若是chat.log.1已經存在,會先把chat.log.1重命名爲chat.log.2。。。最後從新建立 chat.log,繼續輸出日誌信息。它的構造函數是:RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]]),其中filename和mode兩個參數和FileHandler同樣。maxBytes用於指定日誌文件的最大文件大小。若是maxBytes爲0,意味着日誌文件能夠無限大,這時上面描述的重命名過程就不會發生。backupCount用於指定保留的備份文件的個數。好比,若是指定爲2,當上面描述的重命名過程發生時,原有的chat.log.2並不會被改名,而是被刪除。
四、logging.handlers.TimedRotatingFileHandler,這個Handler和RotatingFileHandler相似,不過,它沒有經過判斷文件大小來決定什麼時候從新建立日誌文件,而是間隔必定時間就 自動建立新的日誌文件。重命名的過程與RotatingFileHandler相似,不過新的文件不是附加數字,而是當前時間。它的構造函數是:TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]]),其中filename參數和backupCount參數和RotatingFileHandler具備相同的意義,interval是時間間隔,when參數是一個字符串。表示時間間隔的單位,不區分大小寫。它有如下取值:
S 秒
M 分
H 小時
D 天
W 每星期(interval==0時表明星期一)
midnight 天天凌晨

e.g:

import logging

logger = logging.getLogger("TESE")
logger.setLevel(logging.DEBUG)
# 得到一個logger並定義記錄級別

screen = logging.StreamHandler()
screen.setLevel(logging.DEBUG)
# 定義一個屏幕輸出Handler並定義記錄級別

file = logging.FileHandler("test.log")
file.setLevel(logging.DEBUG)
# 定義一個文件輸出Handler並定義記錄級別

formatter = logging.Formatter("%(asctime)s-%(levelname)s-%(filename)s")
# 定義一個日誌記錄格式

screen.setFormatter(formatter)
file.setFormatter(formatter)
# 爲Handler指定記錄格式

logger.addHandler(screen)
logger.addHandler(file)
# 添加日誌的Handler

logger.debug("This is a debug_log")
logger.info("This is a info_log")
logger.warning("This is a warning_log")
logger.error("This is a error_log")
logger.critical("This is a critical_log")
# 每一個級別的輸出信息

#結果
#屏幕輸出
2017-10-23 14:40:09,892-DEBUG-test.py
2017-10-23 14:40:09,893-INFO-test.py
2017-10-23 14:40:09,893-WARNING-test.py
2017-10-23 14:40:09,893-ERROR-test.py
2017-10-23 14:40:09,893-CRITICAL-test.py
#信息同時寫入test.log文件

9.十、re模塊

re模塊用於對正則表達式的操做。

import re

#經常使用匹配語法
#re.match 從頭開始匹配,e.g:
>>> re.match("a","abc").group()
'a'
>>> re.match("b","abc").group()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

#re.search 匹配包含,e.g:
>>> re.search("b","abc").group()
'b'

#re.findall 把全部匹配到的字符放到以列表中的元素返回,e.g:
>>> re.findall("\w","abcdefg")
['a', 'b', 'c', 'd', 'e', 'f', 'g']

#re.split 以匹配到的字符當作列表分隔符,e.g:
>>> re.split("b","abc")
['a', 'c']

#re.sub 匹配字符並替換
>>> re.sub("b","c","ab")
'ac
#經常使用正則表達式符號

#"." 默認匹配除\n以外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行,e.g:
>>> re.search(".","abcd").group()
'a'
>>> re.search(".","+-*/").group()
'+'

#"^" 匹配字符開頭,若指定flags MULTILINE,這種也能夠匹配上(r"^a","\nabc\neee",flags=re.MULTILINE),e.g:
>>> re.search("^a","abc").group()
'a'
>>> re.search("^b","abc").group()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

#"$" 匹配字符結尾,若指定flags MULTILINE,re.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也能夠匹配上,e.g:
>>> re.search("c$","abc").group()
'c'
>>> re.search("b$","abc").group()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

#"*" 匹配*號前的字符0次或屢次,e.g:
>>> re.findall("ab*","abcabcabc")
['ab', 'ab', 'ab']

#"+" 匹配前一個字符1次或屢次,e.g:
>>> re.findall("a+","abcabcabc")
['a', 'a', 'a']

#"?" 匹配前一個字符1次或0次

#"{m}" 匹配前一個字符m次

#"{n,m}" 匹配前一個字符n到m次

#"[]" 匹配字符集中的任意一個字符。[^]表示取反。
>>> re.search("[ad]","abc").group()
'a'
>>> re.findall("[^a]","abc")
['b', 'c']

#"x|y" 匹配x或y的字符,e.g:
>>> re.search("a|d","abc").group()
'a'

#"()" 分組匹配

#"\A" 只從字符開頭匹配,e.g:
>>> re.search("\Aa","abc").group()
'a'
>>> re.search("\Ab","abc").group()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

#"\Z" 匹配字符結尾,同$

#"\d" 匹配數字0-9

#"\D" 匹配非數字

#"\w" 匹配A-Z、a-z、0-9

#"\W" 匹配非A-Z、a-z、0-9

#"\s" 匹配空白字符、\t、\n、\r ,e.g:
>>> re.search("\s","\nabc").group()
'\n'

#"(?P)" 分組匹配並生成一個字典,e.g:
>>> re.search("(?P<a>a)(?P<b>b)(?P<c>c)","abc").groupdict()
{'a': 'a', 'b': 'b', 'c': 'c'}

#re.I(re.IGNORECASE):忽略大小寫(括號內爲完整寫法)
#re.M(MULTILINE):多行模式,改變'^'和'$'的行爲
#re.S(DOTALL):任意匹配模式,改變"."的行爲

9.十一、subprocess模塊

subprocess模塊用於與系統進行交互,經過子進程來執行系統指令。

#如下在Linux下進行,Windows下結果有所不一樣

#subprocess.run()推薦的經常使用方法
>>> subprocess.run(["df", "-m"])
文件系統        1M-塊   已用   可用 已用% 掛載點
udev             1953      0   1953    0% /dev
tmpfs             395      6    390    2% /run
/dev/sda1      499806 200207 274189   43% /
tmpfs            1975     20   1956    1% /dev/shm
tmpfs               5      1      5    1% /run/lock
tmpfs            1975      0   1975    0% /sys/fs/cgroup
tmpfs             395      1    395    1% /run/user/1000
CompletedProcess(args=['df', '-m'], returncode=0)
>>> subprocess.run("df -m", shell = True)
文件系統        1M-塊   已用   可用 已用% 掛載點
udev             1953      0   1953    0% /dev
tmpfs             395      6    390    2% /run
/dev/sda1      499806 200207 274189   43% /
tmpfs            1975     20   1956    1% /dev/shm
tmpfs               5      1      5    1% /run/lock
tmpfs            1975      0   1975    0% /sys/fs/cgroup
tmpfs             395      1    395    1% /run/user/1000
CompletedProcess(args='df -m', returncode=0)

#subprocess.call()執行命令,返回命令執行結果及執行狀態,成功爲0,失敗非0
>>> subprocess.call(["df", "-h"])
文件系統        容量  已用  可用 已用% 掛載點
udev            2.0G     0  2.0G    0% /dev
tmpfs           395M  6.0M  390M    2% /run
/dev/sda1       489G  196G  268G   43% /
tmpfs           2.0G   26M  2.0G    2% /dev/shm
tmpfs           5.0M  4.0K  5.0M    1% /run/lock
tmpfs           2.0G     0  2.0G    0% /sys/fs/cgroup
tmpfs           395M   48K  395M    1% /run/user/1000
0
>>> subprocess.call(["df", "-t"])
df:選項須要一個參數 -- t
Try 'df --help' for more information.
1

#subprocess.check_call()執行命令,成功執行返回0,失敗則拋出異常
>>> subprocess.check_call(["df", "-m"])
文件系統        1M-塊   已用   可用 已用% 掛載點
udev             1953      0   1953    0% /dev
tmpfs             395      6    390    2% /run
/dev/sda1      499806 200207 274188   43% /
tmpfs            1975     18   1957    1% /dev/shm
tmpfs               5      1      5    1% /run/lock
tmpfs            1975      0   1975    0% /sys/fs/cgroup
tmpfs             395      1    395    1% /run/user/1000
0
>>> subprocess.check_call(["df", "-t"])
df:選項須要一個參數 -- t
Try 'df --help' for more information.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.5/subprocess.py", line 581, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['df', '-t']' returned non-zero exit status 1

#subprocess.getstatusoutput()返回一個元組,第一個元素是執行狀態,第二個元素是執行結果
>>> subprocess.getstatusoutput(["df", "-h"])
(0, '文件系統           1K-塊      已用      可用 已用% 掛載點\nudev             1999728         0   1999728    0% /dev\ntmpfs             404424      6080    398344    2% /run\n/dev/sda1      511801088 205011900 280768172   43% /\ntmpfs            2022108     18836   2003272    1% /dev/shm\ntmpfs               5120         4      5116    1% /run/lock\ntmpfs            2022108         0   2022108    0% /sys/fs/cgroup\ntmpfs             404424        48    404376    1% /run/user/1000')

#subprocess.getoutput()以字符串形式返回執行結果
>>> subprocess.getoutput(["df", "-m"])
'文件系統           1K-塊      已用      可用 已用% 掛載點\nudev             1999728         0   1999728    0% /dev\ntmpfs             404424      6080    398344    2% /run\n/dev/sda1      511801088 205012144 280767928   43% /\ntmpfs            2022108     18836   2003272    1% /dev/shm\ntmpfs               5120         4      5116    1% /run/lock\ntmpfs            2022108         0   2022108    0% /sys/fs/cgroup\ntmpfs             404424        48    404376    1% /run/user/1000'

#subprocess.check_output()
>>> subprocess.check_output(["df", "-m"])
b'\xe6\x96\x87\xe4\xbb\xb6\xe7\xb3\xbb\xe7\xbb\x9f        1M-\xe5\x9d\x97   \xe5\xb7\xb2\xe7\x94\xa8   \xe5\x8f\xaf\xe7\x94\xa8 \xe5\xb7\xb2\xe7\x94\xa8% \xe6\x8c\x82\xe8\xbd\xbd\xe7\x82\xb9\nudev             1953      0   1953    0% /dev\ntmpfs             395      6    390    2% /run\n/dev/sda1      499806 200208 274188   43% /\ntmpfs            1975     20   1956    1% /dev/shm\ntmpfs               5      1      5    1% /run/lock\ntmpfs            1975      0   1975    0% /sys/fs/cgroup\ntmpfs             395      1    395    1% /run/user/1000\n'
#subprocess.Popen()subprocess模塊的底層方法

#可用參數
# args:shell命令,能夠是字符串或者序列類型(如:list,元組)
# bufsize:指定緩衝。0 無緩衝,1 行緩衝,其餘 緩衝區大小,負值 系統緩衝
# stdin, stdout, stderr:分別表示程序的標準輸入、輸出、錯誤句柄
# preexec_fn:只在Unix平臺下有效,用於指定一個可執行對象(callable object),它將在子進程運行以前被調用
# close_sfs:在windows平臺下,若是close_fds被設置爲True,則新建立的子進程將不會繼承父進程的輸入、輸出、錯誤管道。因此不能將close_fds設置爲True同時重定向子進程的標準輸入、輸出與錯誤(stdin, stdout, stderr)。
# shell:同上
# cwd:用於設置子進程的當前目錄
# env:用於指定子進程的環境變量。若是env = None,子進程的環境變量將從父進程中繼承。
universal_newlines:不一樣系統的換行符不一樣,True -> 贊成使用 \n
# startupinfo與createionflags只在windows下有效,將被傳遞給底層的CreateProcess()函數,用於設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等

#e,g:
subprocess.Popen(["df", "-m"], stdout = subprocess.PIPE)
相關文章
相關標籤/搜索