日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

第十章 开箱即用

發(fā)布時(shí)間:2023/12/1 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第十章 开箱即用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

第十章 開箱即用

“開箱即用”(batteries included)最初是由Frank Stajano提出的,指的是Python豐富的標(biāo)準(zhǔn)庫。

模塊

使用import將函數(shù)從外部模塊導(dǎo)入到程序中。

import math math.sin(0)#結(jié)果為:0.0

模塊就是程序

在文件夾中創(chuàng)建一個(gè)test.py,內(nèi)容如下:

#text.py print("hello beyond band!")


位置如下:

sys.path包含一個(gè)目錄(表示為字符串)列表,解釋器將在這些目錄中查找模塊。

import sys sys.path.append('E:\Jupyter_workspace\study\python\book')import text#結(jié)果為:hello beyond band!

程序運(yùn)行完之后會生成一個(gè)__pycache__文件夾,這個(gè)目錄包含處理后的文件,Python能夠更高效地處理它們。
以后再導(dǎo)入這個(gè)模塊時(shí),如果.py文件未發(fā)生變化,Python將導(dǎo)入處理后的文件,否則將重新生成處理后的文件。

導(dǎo)入這個(gè)模塊時(shí),執(zhí)行了其中的代碼。但如果再次導(dǎo)入它,什么事情都不會發(fā)生。
模塊并不是用來執(zhí)行操作(如打印文本)的,而是用于定義變量、函數(shù)、類等。

模塊是用來下定義的

模塊在首次被導(dǎo)入程序時(shí)執(zhí)行。
在模塊中定義的類和函數(shù)以及對其進(jìn)行賦值的變量都將成為模塊的屬性。

1,在模塊中定義函數(shù)
創(chuàng)建hellp.py
內(nèi)容如下:

#hello.py def hello():print("Hello beyond!!!")

在另一個(gè)py文件中導(dǎo)入該模塊

import sys sys.path.append('E:\Jupyter_workspace\study\python\book')import hellohello.hello()#結(jié)果為:Hello beyond!!!

在模塊的全局作用域內(nèi)定義的名稱都可像上面這樣訪問。

為何不在主程序中定義一切呢?
主要是為了重用代碼。通過將代碼放在模塊中,就可在多個(gè)程序中使用它們。

2,在模塊中添加測試代碼
檢查模塊是作為程序運(yùn)行還是被導(dǎo)入另一個(gè)程序。為此,需要使用變量__name__。

在上面的基礎(chǔ)上進(jìn)行測試:

import sys sys.path.append('E:\Jupyter_workspace\study\python\book')import hellohello.hello()#結(jié)果為:Hello beyond!!!__name__#結(jié)果為:'__main__' hello.__name__#結(jié)果為:'hello'

在主程序中(包括解釋器的交互式提示符),變量__name__的值是’__main__’,
而在導(dǎo)入的模塊中,這個(gè)變量被設(shè)置為該模塊的名稱。

一個(gè)包含有條件地執(zhí)行的測試代碼的模塊
創(chuàng)建beyond.py
內(nèi)容如下:

#beyond.py def hello():print("beyond!")def test():hello()if __name__ == '__main__':test()

如果將這個(gè)模塊作為程序運(yùn)行,將執(zhí)行函數(shù)hello;
如果導(dǎo)入它,其行為將像普通模塊一樣。

在另一個(gè)py文件中導(dǎo)入該模塊

import sys sys.path.append('E:\Jupyter_workspace\study\python\book')import beyondbeyond.hello()#結(jié)果為:beyond! beyond.test()#結(jié)果為:beyond!

將測試代碼放在了函數(shù)test中。原本可以將這些代碼直接放在if語句中,但通過將其放在一個(gè)獨(dú)立的測試函數(shù)中,可在程序中導(dǎo)入模塊并對其進(jìn)行測試。

讓模塊可用

1,將模塊放在正確的位置

將模塊放在正確的位置很容易,只需找出Python解釋器到哪里去查找模塊,再將文件放在這個(gè)地方即可。

模塊sys的變量path中找到目錄列表(即搜索路徑)。
如果要打印的數(shù)據(jù)結(jié)構(gòu)太大,一行容納不下,可使用模塊pprint中的函數(shù)pprint(而不是普通print語句)。pprint是個(gè)卓越的打印函數(shù),能夠更妥善地打印輸出。

import sys,pprint pprint.pprint(sys.path)#結(jié)果為: ''' ['','D:\\Anaconda3\\python36.zip','D:\\Anaconda3\\DLLs','D:\\Anaconda3\\lib','D:\\Anaconda3','D:\\Anaconda3\\lib\\site-packages','D:\\Anaconda3\\lib\\site-packages\\Babel-2.5.0-py3.6.egg','D:\\Anaconda3\\lib\\site-packages\\win32','D:\\Anaconda3\\lib\\site-packages\\win32\\lib','D:\\Anaconda3\\lib\\site-packages\\Pythonwin','D:\\Anaconda3\\lib\\site-packages\\IPython\\extensions','C:\\Users\\yanyu\\.ipython','E:\\Jupyter_workspace\\study\\python\x08ook','E:\\Jupyter_workspace\\study\\python\x08ook','E:\\Jupyter_workspace\\study\\python\x08ook','E:\\Jupyter_workspace\\study\\python\x08ook','E:\\Jupyter_workspace\\study\\python\x08ook','E:\\Jupyter_workspace\\study\\python\x08ook','E:\\Jupyter_workspace\\study\\python\x08ook','E:\\Jupyter_workspace\\study\\python\x08ook','E:\\Jupyter_workspace\\study\\python\x08ook'] '''

每個(gè)字符串都表示一個(gè)位置,如果要讓解釋器能夠找到模塊,可將其放在其中任何一個(gè)位置中。目錄site-packages是最佳的選擇,因?yàn)樗褪怯脕矸胖媚K的。

只要模塊位于類似于site-packages這樣的地方,所有的程序就都能夠?qū)胨?/strong>
將上述的beyond.py文件放入到site-packages文件夾下。

故在其他程序中可以直接導(dǎo)入即可:

import beyond beyond.hello()#結(jié)果為:beyond!

2,告訴解析器到哪里去查找

將模塊放在正確的位置可能不是合適的解決方案,其中的原因很多
1,不希望Python解釋器的目錄中充斥著你編寫的模塊。
2,沒有必要的權(quán)限,無法將文件保存到Python解釋器的目錄中。
3,想將模塊放在其他地方。
4,如果將模塊放在其他地方,就必須告訴解釋器到哪里去查找。
標(biāo)準(zhǔn)做法解釋
1,將模塊所在的目錄包含在環(huán)境變量PYTHONPATH中環(huán)境變量PYTHONPATH的內(nèi)容隨操作系統(tǒng)而異,但它基本上類似于sys.path,也是一個(gè)目錄列表。
2,使用路徑配置文件這些文件的擴(kuò)展名為.pth,位于一些特殊目錄中,包含要添加到sys.path中的目錄。

為組織模塊,可將其編組為包(package)。
包其實(shí)就是另一種模塊(可包含其他模塊的模塊)。

模塊存儲在擴(kuò)展名為.py的文件中,而則是一個(gè)目錄。

要被Python視為包,目錄必須包含文件__init__.py。

要將模塊加入包中,只需將模塊文件放在包目錄中即可。還可以在包中嵌套其他包。

按照下面的五個(gè)文件夾路徑創(chuàng)建對應(yīng)的文件和文件夾

文件/目錄描述
~/python/PYTHONPATH中的目錄
~/python/drawing/包目錄(包drawing)
~/python/drawing/__init__.py包代碼(模塊drawing)
~/python/drawing/colors.py模塊colors
~/python/drawing/shapes.py模塊shapes
import drawing#導(dǎo)入drawing包 import drawing.colors#導(dǎo)入drawing包中的模塊colors from drawing import shapes#導(dǎo)入模塊shapes ''' 執(zhí)行第1條語句后,便可使用目錄drawing中文件__init__.py的內(nèi)容,但不能使用模塊shapes和colors的內(nèi)容。 執(zhí)行第2條語句后,便可使用模塊colors,但只能通過全限定名drawing.colors來使用。 執(zhí)行第3條語句后,便可使用簡化名(即shapes)來使用模塊shapes。 '''

探索模塊

模塊包含什么

接下來以一個(gè)名為copy的標(biāo)準(zhǔn)模塊來進(jìn)行解釋:

import copy

沒有引發(fā)異常,說明確實(shí)有這樣的模塊。

1,使用dir
函數(shù)dir,它列出對象的所有屬性(對于模塊,它列出所有的函數(shù)、類、變量等)
在這些名稱中,有幾個(gè)以下劃線打頭。根據(jù)約定,這意味著它們并非供外部使用。
使用一個(gè)簡單的列表推導(dǎo)將這些名稱過濾掉。
[n for n in dir(copy) if not n.startswith('_')] 結(jié)果包含dir(copy)返回的不以下劃線打頭的名稱,

import copy dir(copy)#結(jié)果為: """ ['Error','__all__','__builtins__','__cached__','__doc__','__file__','__loader__','__name__','__package__','__spec__','_copy_dispatch','_copy_immutable','_deepcopy_atomic','_deepcopy_dict','_deepcopy_dispatch','_deepcopy_list','_deepcopy_method','_deepcopy_tuple','_keep_alive','_reconstruct','copy','deepcopy','dispatch_table','error'] """[n for n in dir(copy) if not n.startswith('_')]#結(jié)果為:['Error', 'copy', 'deepcopy', 'dispatch_table', 'error']

2,變量__all__
由上述的代碼段可知,在dir(copy)返回的完整清單中,包含名稱__all__。
__all__這個(gè)變量包含一個(gè)列表,它與前面使用列表推導(dǎo)創(chuàng)建的列表類似,但是在模塊內(nèi)部設(shè)置的。

import copy copy.__all__#結(jié)果為:['Error', 'copy', 'deepcopy']

使用help獲取幫助

使用help獲取有關(guān)函數(shù)copy的信息

help(copy.copy)#結(jié)果為: ''' Help on function copy in module copy:copy(x)Shallow copy operation on arbitrary Python objects.See the module's __doc__ string for more info. '''

上述幫助信息指出,函數(shù)copy只接受一個(gè)參數(shù)x,且執(zhí)行的是淺復(fù)制。
幫助信息是從函數(shù)copy的文檔字符串中提取的

print(copy.copy.__doc__)#結(jié)果為: ''' Shallow copy operation on arbitrary Python objects.See the module's __doc__ string for more info. '''

相比于直接查看文檔字符串,使用help的優(yōu)點(diǎn)是可獲取更多的信息,如函數(shù)的特征標(biāo)(即它接受的參數(shù))。

對模塊copy本身調(diào)用help

help(copy)#結(jié)果為: ''' Help on module copy:NAMEcopy - Generic (shallow and deep) copying operations.DESCRIPTIONInterface summary:import copyx = copy.copy(y) # make a shallow copy of yx = copy.deepcopy(y) # make a deep copy of yFor module specific errors, copy.Error is raised.The difference between shallow and deep copying is only relevant forcompound objects (objects that contain other objects, like lists orclass instances).- A shallow copy constructs a new compound object and then (to theextent possible) inserts *the same objects* into it that theoriginal contains.- A deep copy constructs a new compound object and then, recursively,inserts *copies* into it of the objects found in the original.Two problems often exist with deep copy operations that don't existwith shallow copy operations:a) recursive objects (compound objects that, directly or indirectly,contain a reference to themselves) may cause a recursive loopb) because deep copy copies *everything* it may copy too much, e.g.administrative data structures that should be shared even betweencopiesPython's deep copy operation avoids these problems by:a) keeping a table of objects already copied during the currentcopying passb) letting user-defined classes override the copying operation or theset of components copiedThis version does not copy types like module, class, function, method,nor stack trace, stack frame, nor file, socket, window, nor array, norany similar types.Classes can use the same interfaces to control copying that they useto control pickling: they can define methods called __getinitargs__(),__getstate__() and __setstate__(). See the documentation for module"pickle" for information on these methods.CLASSESbuiltins.Exception(builtins.BaseException)Errorclass Error(builtins.Exception)| Common base class for all non-exit exceptions.| | Method resolution order:| Error| builtins.Exception| builtins.BaseException| builtins.object| | Data descriptors defined here:| | __weakref__| list of weak references to the object (if defined)| | ----------------------------------------------------------------------| Methods inherited from builtins.Exception:| | __init__(self, /, *args, **kwargs)| Initialize self. See help(type(self)) for accurate signature.| | __new__(*args, **kwargs) from builtins.type| Create and return a new object. See help(type) for accurate signature.| | ----------------------------------------------------------------------| Methods inherited from builtins.BaseException:| | __delattr__(self, name, /)| Implement delattr(self, name).| | __getattribute__(self, name, /)| Return getattr(self, name).| | __reduce__(...)| helper for pickle| | __repr__(self, /)| Return repr(self).| | __setattr__(self, name, value, /)| Implement setattr(self, name, value).| | __setstate__(...)| | __str__(self, /)| Return str(self).| | with_traceback(...)| Exception.with_traceback(tb) --| set self.__traceback__ to tb and return self.| | ----------------------------------------------------------------------| Data descriptors inherited from builtins.BaseException:| | __cause__| exception cause| | __context__| exception context| | __dict__| | __suppress_context__| | __traceback__| | argsFUNCTIONScopy(x)Shallow copy operation on arbitrary Python objects.See the module's __doc__ string for more info.deepcopy(x, memo=None, _nil=[])Deep copy operation on arbitrary Python objects.See the module's __doc__ string for more info.DATA__all__ = ['Error', 'copy', 'deepcopy']FILEd:\anaconda3\lib\copy.py '''

文檔

文檔是有關(guān)模塊信息的自然來源

例如,你可能想知道range的參數(shù)是什么?
在這種情況下,與其在Python圖書或標(biāo)準(zhǔn)Python文檔中查找對range的描述,不如直接檢查這個(gè)函數(shù)。

print(range.__doc__)#結(jié)果為: ''' range(stop) -> range object range(start, stop[, step]) -> range objectReturn an object that produces a sequence of integers from start (inclusive) to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1. start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3. These are exactly the valid indices for a list of 4 elements. When step is given, it specifies the increment (or decrement). '''

Python庫參考手冊”(https://docs.python.org/library)

使用源代碼

要學(xué)習(xí)Python,閱讀源代碼是除動手編寫代碼外的最佳方式。
假設(shè)你要閱讀標(biāo)準(zhǔn)模塊copy的代碼,可以在什么地方找到呢?

print(copy.__file__)#結(jié)果為:D:\Anaconda3\lib\copy.py

你可在代碼編輯器(如IDLE)中打開文件copy.py,并開始研究其工作原理。

標(biāo)準(zhǔn)庫:一些深受歡迎的模塊

sys

模塊sys讓你能夠訪問與Python解釋器緊密相關(guān)的變量和函數(shù)。

函數(shù)/變量描述
argv命令行參數(shù),包括腳本名
exit([arg])退出當(dāng)前程序,可通過可選參數(shù)指定返回值或錯(cuò)誤消息
modules一個(gè)字典,將模塊名映射到加載的模塊
path一個(gè)列表,包含要在其中查找模塊的目錄的名稱
platform一個(gè)平臺標(biāo)識符,如sunos5或win32
stdin標(biāo)準(zhǔn)輸入流——一個(gè)類似于文件的對象
stdout標(biāo)準(zhǔn)輸出流——一個(gè)類似于文件的對象
stderr標(biāo)準(zhǔn)錯(cuò)誤流——一個(gè)類似于文件的對象

反轉(zhuǎn)并打印命令行參數(shù)
創(chuàng)建了一個(gè)sys.argv的副本,也可修改sys.argv。

import sys args = sys.argv[1:] args.reverse() print(' '.join(args))#結(jié)果為:C:\Users\yanyu\AppData\Roaming\jupyter\runtime\kernel-17c0e23a-ea6e-40f9-98dc-68588128f0cc.json -fprint(' '.join(reversed(sys.argv[1:])))#結(jié)果為:C:\Users\yanyu\AppData\Roaming\jupyter\runtime\kernel-17c0e23a-ea6e-40f9-98dc-68588128f0cc.json -f

os

模塊os讓你能夠訪問多個(gè)操作系統(tǒng)服務(wù)。

os及其子模塊os.path還包含多個(gè)查看、創(chuàng)建和刪除目錄及文件的函數(shù),以及一些操作路徑的函數(shù)(例如,os.path.split和os.path.join讓你在大多數(shù)情況下都可忽略os.pathsep)。

函數(shù)/變量描述
environ包含環(huán)境變量的映射
system(command)在子shell中執(zhí)行操作系統(tǒng)命令
sep路徑中使用的分隔符
pathsep分隔不同路徑的分隔符
linesep行分隔符(’\n’、’\r’或’\r\n’)
urandom(n)返回n個(gè)字節(jié)的強(qiáng)加密隨機(jī)數(shù)據(jù)

要訪問環(huán)境變量PYTHONPATH,可使用表達(dá)式os.environ['PYTHONPATH']。

變量os.sep是用于路徑名中的分隔符。
在Windows中,標(biāo)準(zhǔn)分隔符為\\(這種Python語法表示單個(gè)反斜杠)
在UNIX(以及macOS的命令行Python版本)中,標(biāo)準(zhǔn)分隔符為/。

變量os.linesep是用于文本文件中的行分隔符:
在UNIX/OS X中為單個(gè)換行符(\n)
在Windows中為回車和換行符(\r\n)

啟動圖形用戶界面程序,如Web瀏覽器
在UNIX中:假設(shè)目錄為/usr/bin/firefox

import os os.system('/usr/bin/firefox')

在Windows中:假設(shè)目錄為C:\Program Files\Mozilla Firefox
這里用引號將Program Files和Mozilla Firefox括起來了。
如果不這樣做,底層shell將受阻于空白處(對于PYTHONPATH中的路徑,也必須這樣做)。
另外,這里必須使用反斜桿,因?yàn)?Windows shell 無法識別斜杠。

import os os.system(r'C:\"Program Files"\"Mozilla Firefox"\firefox.exe')

Windows特有的函數(shù)os.startfile,也可以完成該操作

import os os.startfile(r'C:\Program Files\Mozilla Firefox\firefox.exe')

就啟動Web瀏覽器這項(xiàng)任務(wù)而言,使用模塊webbrowser,這個(gè)模塊包含一個(gè)名為open的函數(shù),讓你能夠啟動默認(rèn)Web瀏覽器并打開指定的URL。

import webbrowser webbrowser.open('https://beyondyanyu.blog.csdn.net/')

fileinput

模塊fileinput讓你能夠輕松地迭代一系列文本文件中的所有行。

函數(shù)描述
input([files[, inplace[, backup]]])幫助迭代多個(gè)輸入流中的行
filename()返回當(dāng)前文件的名稱
lineno()返回(累計(jì)的)當(dāng)前行號
filelineno()返回在當(dāng)前文件中的行號
isfirstline()檢查當(dāng)前行是否是文件中的第一行
isstdin()檢查最后一行是否來自sys.stdin
nextfile()關(guān)閉當(dāng)前文件并移到下一個(gè)文件
close()關(guān)閉序列

fileinput.input是其中最重要的函數(shù),它返回一個(gè)可在for循環(huán)中進(jìn)行迭代的對象。

在Python腳本中添加行號
rstrip是一個(gè)字符串方法,它將刪除指定字符串兩端的空白,并返回結(jié)果

import fileinputfor line in fileinput.input(inplace=True):line = line.rstrip()num = fileinput.lineno()print('{:<50} # {:2d}'.format(line,num))

集合、堆和雙端隊(duì)列

1,集合
集合是由內(nèi)置類set實(shí)現(xiàn)的,這意味著你可直接創(chuàng)建集合,而無需導(dǎo)入模塊sets。

set(range(1,30,2))#結(jié)果為:{1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29}

僅使用花括號這將創(chuàng)建一個(gè)空字典

type({})#結(jié)果為:dict

集合主要用于成員資格檢查,因此將忽略重復(fù)的元素

{0, 1, 2, 3, 0, 1, 2, 3, 4, 5}#結(jié)果為:{0, 1, 2, 3, 4, 5}

集合中元素的排列順序是不確定的

{'hjj', 'sq', 'hjq', 'hjj', 'hjq'}#結(jié)果為:{'hjj', 'hjq', 'sq'}

計(jì)算兩個(gè)集合的并集,可對其中一個(gè)集合調(diào)用方法union也可使用按位或運(yùn)算符|

a = {1,2,3} b = {2,3,4} a.union(b)#結(jié)果為:{1, 2, 3, 4} a | b#結(jié)果為:{1, 2, 3, 4}

還有其他一些方法和對應(yīng)的運(yùn)算符

a = {1,2,3} b = {2,3,4} c = a & b c.issubset(a)#結(jié)果為:Truec <= a#結(jié)果為:True c.issuperset(a)#結(jié)果為:Falsec >= a#結(jié)果為:False a.intersection(b)#結(jié)果為:{2, 3}a & b#結(jié)果為:{2, 3} a.difference(b)#結(jié)果為:{1}a - b#結(jié)果為:{1} a.symmetric_difference(b)#結(jié)果為:{1, 4}a ^ b#結(jié)果為:{1, 4}a.copy()#結(jié)果為:{1, 2, 3} a.copy() is a#結(jié)果為:False

集合是可變的,因此不能用作字典中的鍵。
集合只能包含不可變(可散列)的值,因此不能包含其他集合。
frozenset類型,它表示不可變(可散列)的集合。

構(gòu)造函數(shù)frozenset創(chuàng)建給定集合的副本。
在需要將集合作為另一個(gè)集合的成員或字典中的鍵時(shí),frozenset很有用。

a = set() b = set() a.add(b)#報(bào)錯(cuò)!!! ''' TypeError Traceback (most recent call last) <ipython-input-48-07ed0deb5758> in <module>()1 a = set()2 b = set() ----> 3 a.add(b)TypeError: unhashable type: 'set' '''a.add(frozenset(b)) print(a.add(frozenset(b)))#結(jié)果為:None print(a)#結(jié)果為:{frozenset()} print(b)#結(jié)果為:set()

2,堆
堆(heap),它是一種優(yōu)先隊(duì)列。
優(yōu)先隊(duì)列讓能夠以任意順序添加對象,并隨時(shí)(可能是在兩次添加對象之間)找出(并刪除)最小的元素。

Python沒有獨(dú)立的堆類型,而只有一個(gè)包含一些堆操作函數(shù)的模塊。這個(gè)模塊名為heapq(其中的q表示隊(duì)列),它包含6個(gè)函數(shù)。

函數(shù)描述
heappush(heap, x)將x壓入堆中
heappop(heap)從堆中彈出最小的元素
heapify(heap)讓列表具備堆特征
heapreplace(heap, x)彈出最小的元素,并將x壓入堆中
nlargest(n, iter)返回iter中n個(gè)最大的元素
nsmallest(n, iter)返回iter中n個(gè)最小的元素

函數(shù)heappush用于在堆中添加一個(gè)元素。

from heapq import * from random import shuffle data = list(range(10)) shuffle(data) heap = [] for n in data:heappush(heap,n)heap#結(jié)果為:[0, 1, 5, 2, 4, 7, 9, 8, 3, 6]#位置i處的元素總是大于位置i // 2處的元素(反過來說就是小于位置2 * i和2 * i + 1處的元素)。這是底層堆算法的基礎(chǔ),稱為堆特征(heap property)。 heappush(heap,0.5) heap#結(jié)果為:[0, 0.5, 5, 2, 1, 7, 9, 8, 3, 6, 4]heappop(heap)#結(jié)果為:0 heappop(heap)#結(jié)果為:0.5 heappop(heap)#結(jié)果為:1heap#結(jié)果為:[2, 3, 5, 6, 4, 7, 9, 8]#函數(shù)heapify通過執(zhí)行盡可能少的移位操作將列表變成合法的堆(即具備堆特征)。 heap = [5,8,0,3,6,7,9,1,4,2] heapify(heap) heap#結(jié)果為:[0, 1, 5, 3, 2, 7, 9, 8, 4, 6]#函數(shù)heapreplace從堆中彈出最小的元素,再壓入一個(gè)新元素。 heapreplace(heap,0.5)#結(jié)果為:0 heap#結(jié)果為:[0.5, 1, 5, 3, 2, 7, 9, 8, 4, 6] heapreplace(heap,10)#結(jié)果為:0.5 heap#結(jié)果為:[1, 2, 5, 3, 6, 7, 9, 8, 4, 10]

3,雙端隊(duì)列
在需要按添加元素的順序進(jìn)行刪除時(shí),雙端隊(duì)列很有用。
在模塊collections中,包含類型deque以及其他幾個(gè)集合(collection)類型。

from collections import deque q = deque(range(5)) q.append(5) q.appendleft(6) q#結(jié)果為:deque([6, 0, 1, 2, 3, 4, 5])q.pop()#結(jié)果為:5 q.popleft()#結(jié)果為:6q.rotate(3) q#結(jié)果為:deque([2, 3, 4, 0, 1])q.rotate(-1) q#結(jié)果為:deque([3, 4, 0, 1, 2])

雙端隊(duì)列支持在隊(duì)首(左端)高效地附加和彈出元素,還可高效地旋轉(zhuǎn)元素(將元素向右或向左移,并在到達(dá)一端時(shí)環(huán)繞到另一端)。

雙端隊(duì)列對象還包含方法extendextendleft,其中extend類似于相應(yīng)的列表方法,而extendleft類似于appendleft。
用于extendleft的可迭代對象中的元素將按相反的順序出現(xiàn)在雙端隊(duì)列中。

time

模塊time包含用于獲取當(dāng)前時(shí)間、操作時(shí)間和日期、從字符串中讀取日期、將日期格式化為字符串的函數(shù)。

元組(2008, 1, 21, 12, 2, 56, 0, 21, 0)表示2008年1月21日12時(shí)2分56秒。這一天是星期一,2008年的第21天。

索引字段值
0如2000、2001等
1范圍1~1
2范圍1~31
3時(shí)范圍0~23
4范圍0~59
5范圍0~61,這考慮到了閏一秒和閏兩秒的情況。
6星期范圍0~6,其中0表示星期一
7儒略日范圍1~366
8夏令時(shí)0、1或-1,夏令時(shí)數(shù)字是一個(gè)布爾值(True或False),但如果你使用-1,那么mktime[將時(shí)間元組轉(zhuǎn)換為時(shí)間戳(從新紀(jì)元開始后的秒數(shù))的函數(shù)]可能得到正確的值。
函數(shù)描述
asctime([tuple])將時(shí)間元組轉(zhuǎn)換為字符串
localtime([secs])將秒數(shù)轉(zhuǎn)換為表示當(dāng)?shù)貢r(shí)間的日期元組
mktime(tuple)將時(shí)間元組轉(zhuǎn)換為當(dāng)?shù)貢r(shí)間
sleep(secs)休眠(什么都不做)secs秒
strptime(string[, format])將字符串轉(zhuǎn)換為時(shí)間元組
time()當(dāng)前時(shí)間(從新紀(jì)元開始后的秒數(shù),以UTC為準(zhǔn))

函數(shù)time.asctime將當(dāng)前時(shí)間轉(zhuǎn)換為字符串

import time time.asctime()#結(jié)果為:'Sun Jan 16 10:41:41 2022'

兩個(gè)較新的與時(shí)間相關(guān)的模塊:datetime和timeit。
前者提供了日期和時(shí)間算術(shù)支持,而后者可幫助你計(jì)算代碼段的執(zhí)行時(shí)間。

random

模塊random包含生成偽隨機(jī)數(shù)的函數(shù),有助于編寫模擬程序或生成隨機(jī)輸出的程序。
雖然這些函數(shù)生成的數(shù)字好像是完全隨機(jī)的,但它們背后的系統(tǒng)是可預(yù)測的。
真正的隨機(jī)(如用于加密或?qū)崿F(xiàn)與安全相關(guān)的功能),應(yīng)考慮使用模塊os中的函數(shù)urandom。

函數(shù)描述
random()返回一個(gè)0~1(含)的隨機(jī)實(shí)數(shù)
getrandbits(n)以長整數(shù)方式返回n個(gè)隨機(jī)的二進(jìn)制位
uniform(a, b)返回一個(gè)a~b(含)的隨機(jī)實(shí)數(shù)
randrange([start], stop, [step])從range(start, stop, step)中隨機(jī)地選擇一個(gè)數(shù)
choice(seq)從序列seq中隨機(jī)地選擇一個(gè)元素
shuffle(seq[, random])就地打亂序列seq
sample(seq, n)從序列seq中隨機(jī)地選擇n個(gè)值不同的元素

函數(shù)random.random是最基本的隨機(jī)函數(shù)之一,它返回一個(gè)0~1(含)的偽隨機(jī)數(shù)。

首先,獲取表示時(shí)間段(1998年)上限和下限的實(shí)數(shù)。為此,可使用時(shí)間元組來表示日期(將星期、儒略日和夏令時(shí)都設(shè)置為?1,讓Python去計(jì)算它們的正確值),并對這些元組調(diào)用mktime
接下來,以均勻的方式生成一個(gè)位于該范圍內(nèi)(不包括上限)的隨機(jī)數(shù)
然后,將這個(gè)數(shù)轉(zhuǎn)換為易于理解的日期。

from random import * from time import * date1 = (1998,12,2,0,0,0,-1,-1,-1) time1 = mktime(date1) date2 = (1999,7,5,0,0,0,-1,-1,-1) time2 = mktime(date2)random_time = uniform(time1, time2) print(asctime(localtime(random_time)))#結(jié)果為:Fri Feb 5 20:55:09 1999

詢問用戶要擲多少個(gè)骰子、每個(gè)骰子有多少面。擲骰子的機(jī)制是使用randrange和for循環(huán)實(shí)現(xiàn)。

from random import randrange num = int(input('How many dice?')) sides = int(input('How many sides per die?')) sum = 0 for i in range(num):sum += randrange(sides) + 1 print("The result is",sum)#結(jié)果為: ''' How many dice?3 How many sides per die?6 The result is 17 '''

shelve和json

1,一個(gè)潛在的陷阱

import shelve s = shelve.open('database.dat')s['x'] = ['a','b','c'] s['x'].append('d') s['x']#結(jié)果為:['a', 'b', 'c']

‘d’消失了
列表[‘a(chǎn)’, ‘b’, ‘c’]被存儲到s的’x’鍵下。
獲取存儲的表示,并使用它創(chuàng)建一個(gè)新列表,再將’d’附加到這個(gè)新列表末尾,但這個(gè)修改后的版本未被存儲!
最后,再次獲取原來的版本——其中沒有’d’。

解決方法:

import shelve s = shelve.open('database.dat')temp = s['x'] temp.append('d') s['x'] = temp s['x']

2,一個(gè)簡單的數(shù)據(jù)庫示例

import sys,shelvedef store_person(db):pid = input("Enter unique ID number:")person = {}person['name'] = input("Enter name:")person['age'] = input("Enter age:")person['phone'] = input('Enter phone number:')db[pid] = persondef lookup_person(db):pid = input("Enter ID number:")fileld = input("What would you like to know?(name,age,phone)")fileld = field.strip.lower()print(fileld.capitablize() + ':', db[pid][field])def print_help():print("The available commands are:")print("store: Stores information about a person")print("lookup: Looks up a person from ID number")print("quit: Save changes and exit")print("?: Prints this message")def enter_command():cmd = input("Enter command(? for help):")cmd = cmd.strip().lower()def main():database = shelve.open("E:\\Jupyter_workspace\\study\\python\\book\\database.dat")try:while True:cmd = enter_command()if cmd == 'store':store_person(database)elif cmd == 'lookup':lookup_person(database)elif cmd == '?':print_help()elif cmd == 'quit':returnfinally:database.close()if name == '__main__':main()

re

模塊re提供了對正則表達(dá)式的支持。

1,正則表達(dá)式是什么?
正則表達(dá)式是可匹配文本片段的模式。

  • 通配符
    句點(diǎn)與除換行符外的任何字符都匹配,被稱為通配符(wildcard)。
    正則表達(dá)式’.ython‘與字符串’python’和’jython’都匹配,但不與’cpython’、'ython’等字符串匹配,因?yàn)榫潼c(diǎn)只與一個(gè)字符匹配,而不與零或兩個(gè)字符匹配
  • 對特殊字符進(jìn)行轉(zhuǎn)義
    普通字符只與自己匹配,但特殊字符的情況完全不同。
    要讓特殊字符的行為與普通字符一樣,可對其進(jìn)行轉(zhuǎn)義。
    使用模式’python\\.org’,它只與’python.org'匹配。
    為表示模塊re要求的單個(gè)反斜杠,需要在字符串中書寫兩個(gè)反斜杠,讓解釋器對其進(jìn)行轉(zhuǎn)義。
    這里包含兩層轉(zhuǎn)義:解釋器執(zhí)行的轉(zhuǎn)義和模塊re執(zhí)行的轉(zhuǎn)義。
    也可使用原始字符串,如r'python\.org'。
  • 字符集
    用方括號將一個(gè)子串括起,創(chuàng)建一個(gè)所謂的字符集。字符集只能匹配一個(gè)字符。
    '[pj]ython‘與’python‘和’jython'都匹配,但不與其他字符串匹配。
    '[a-z]'與a~z的任何字母都匹配。
    '[a-zA-Z0-9]'與大寫字母、小寫字母和數(shù)字都匹配。
    '[^abc]'與除a、b和c外的其他任何字符都匹配。
  • 二選一和子模式
    ‘python|perl’,只匹配字符串’python‘和’perl’,也可重寫為’p(ython|erl)’。
    單個(gè)字符也可稱為子模式
  • 可選模式和重復(fù)模式
    通過在子模式后面加上問號,可將其指定為可選的,即可包含可不包含。
    r'(http://)?(www\.)?python\.org
    只與下面這些字符串匹配:
    http://www.python.org
    http://python.org
    www.python.org
    python.org

問號表示可選的子模式可出現(xiàn)一次,也可不出現(xiàn)。
(pattern)*:pattern可重復(fù)0、1或多次。
(pattern)+:pattern可重復(fù)1或多次。
(pattern){m,n}:模式可從父m~n次。

r'w*\.python\.org'與’www.python.org‘匹配,也與’.python.org’、’ww.python.org‘和’wwwwwww.python.org‘匹配。同樣,r'w+\.python\.org'與’w.python.org‘匹配,但與’.python. org‘不匹配,而r'w{3,4}\.python\.org'只與’www.python.org‘和’wwww.python.org'匹配。

  • 字符串的開頭和末尾
    查找與模式匹配的子串
    字符串’www.python.org‘中的子串’www‘與模式’w+‘匹配
    確定字符串的開頭是否與模式’ht+p’匹配,為此可使用脫字符(’^’)來指出這一點(diǎn)。
    '^ht+p‘與’http://python.org‘和’htttttp://python.org‘匹配,但與’www.http.org'不匹配。
    同樣,要指定字符串末尾,可使用美元符號($)。

2,模塊re的內(nèi)容
模塊re包含多個(gè)使用正則表達(dá)式的函數(shù)

函數(shù)描述
compile(pattern[, flags])根據(jù)包含正則表達(dá)式的字符串創(chuàng)建模式對象
search(pattern, string[, flags])在字符串中查找模式
match(pattern, string[, flags])在字符串開頭匹配模式
split(pattern, string[, maxsplit=0])根據(jù)模式來分割字符串
findall(pattern, string)返回一個(gè)列表,其中包含字符串中所有與模式匹配的子串
sub(pat, repl, string[, count=0])將字符串中與模式pat匹配的子串都替換為repl
escape(string)對字符串中所有的正則表達(dá)式特殊字符都進(jìn)行轉(zhuǎn)義

函數(shù)re.compile將用字符串表示的正則表達(dá)式轉(zhuǎn)換為模式對象,以提高匹配效率。

函數(shù)re.search在給定字符串中查找第一個(gè)與指定正則表達(dá)式匹配的子串。如果找到這樣的子串,將返回MatchObject(結(jié)果為真),否則返回None(結(jié)果為假)。鑒于返回值的這種特征,可在條件語句中使用這個(gè)函數(shù)

import repat = "beyond" string = "I like the beyond band" if re.search(pat, string):print('Found it!') #結(jié)果為:Found it!

函數(shù)re.split根據(jù)與模式匹配的子串來分割字符串。
使用re.split時(shí),可以空格和逗號為分隔符來分割字符串。

import resome_text = 'alpha, beta,,,,gamma delta' re.split('[, ]+', some_text)#結(jié)果為:['alpha', 'beta', 'gamma', 'delta']#如果模式包含圓括號,將在分割得到的子串之間插入括號中的內(nèi)容。 re.split('o(o)','foobar')#結(jié)果為:['f', 'o', 'bar']#參數(shù)maxsplit指定最多分割多少次。 re.split('[, ]+', some_text, maxsplit=2)#結(jié)果為:['alpha', 'beta', 'gamma delta'] re.split('[, ]+', some_text, maxsplit=1)#結(jié)果為:['alpha', 'beta,,,,gamma delta']#函數(shù)re.findall返回一個(gè)列表,其中包含所有與給定模式匹配的子串。 #要找出字符串包含的所有單詞 pat = '[a-zA-Z]+' text = '"Hm... Err -- are you sure?" he said, sounding insecure.' re.findall(pat, text)#結(jié)果為:['Hm', 'Err', 'are', 'you', 'sure', 'he', 'said', 'sounding', 'insecure']#查找所有的標(biāo)點(diǎn)符號 pat = r'[.?\-",]+' re.findall(pat, text)#結(jié)果為:['"', '...', '--', '?"', ',', '.']#函數(shù)re.sub從左往右將與模式匹配的子串替換為指定內(nèi)容。 pat = '{name}' text = 'Dear {name}...' re.sub(pat, 'Mr. Gumby', text)#結(jié)果為:'Dear Mr. Gumby...'#re.escape是一個(gè)工具函數(shù) re.escape('www.python.org')#結(jié)果為:'www\\.python\\.org' re.escape('But where is the ambiguity?')#結(jié)果為:'But\\ where\\ is\\ the\\ ambiguity\\?'

3,匹配對象和編組
在模塊re中,查找與模式匹配的子串的函數(shù)都在找到時(shí)返回MatchObject對象。
這種對象包含與模式匹配的子串的信息,還包含模式的哪部分與子串的哪部分匹配的信息。這些子串部分稱為編組(group)

編組就是放在圓括號內(nèi)的子模式,它們是根據(jù)左邊的括號數(shù)編號的,其中編組0指的是整個(gè)模式。

’There (was a (wee) (cooper)) who (lived in Fyfe)’
包含如下編組:
0 There was a wee cooper who lived in Fyfe
1 was a wee cooper
2 wee
3 cooper
4 lived in Fyfe

r’www.(.+).com$’
編組0包含整個(gè)字符串,而編組1包含’www.‘和’.com’之間的內(nèi)容。

方法描述
group([group1, …])獲取與給定子模式(編組)匹配的子串
start([group])返回與給定編組匹配的子串的起始位置
end([group])返回與給定編組匹配的子串的終止位置(與切片一樣,不包含終止位置)
span([group])返回與給定編組匹配的子串的起始和終止位置

方法group返回與模式中給定編組匹配的子串。如果沒有指定編組號,則默認(rèn)為0。
如果只指定了一個(gè)編組號(或使用默認(rèn)值0),將只返回一個(gè)字符串;否則返回一個(gè)元組,其中包含與給定編組匹配的子串。
方法start返回與給定編組(默認(rèn)為0,即整個(gè)模式)匹配的子串的起始索引。
方法end類似于start,但返回終止索引加1
方法span返回一個(gè)元組,其中包含與給定編組(默認(rèn)為0,即整個(gè)模式)匹配的子串的起始索引和終止索引。

import re m = re.match(r'www\.(.*)\..{3}', 'www.beyondyanyu.net')m.group(1)#結(jié)果為:4 m.end(1)#結(jié)果為:15 m.span(1)#結(jié)果為:(4,15)

4,替換中的組號和函數(shù)
將’*something*‘替換為’<em>something</em>’

import re#首先開始創(chuàng)建模板: emphasis_pattern = r'\*([^\*]+)\*'''' 上下這兩條正則表達(dá)式等價(jià),很顯然下面的加有注解很人性化。 '''emphasis_pattern = re.compile(r''' \* #起始突出標(biāo)志---一個(gè)星號 ( #與要突出的內(nèi)容匹配的編組的起始位置 [^\*]+ #與除星號外的其他字符都匹配 ) #編組到此結(jié)束 \* #結(jié)束突出標(biāo)志 ''',re.VERBOSE)re.sub(emphasis_pattern, r'<em>\1</em>', 'Hello, *world*!')#結(jié)果為:'Hello, <em>world</em>!'

重復(fù)運(yùn)算符默認(rèn)是貪婪的,這意味著它們將匹配盡可能多的內(nèi)容。

import reemphasis_pattern = r'\*(.+)\*' re.sub(emphasis_pattern, r'<em>\1</em>', '*This* is *it*!')#結(jié)果為:'<em>This* is *it</em>!'

這個(gè)模式匹配了從第一個(gè)星號到最后一個(gè)星號的全部內(nèi)容,其中包含另外兩個(gè)星號!這就是貪婪的意思:能匹配多少就匹配多少。

在后面加上問號來將其指定為非貪婪

import reemphasis_pattern = r'\*\*(.+?)\*\*' re.sub(emphasis_pattern, r'<em>\1</em>', '**This** is **it**!')#結(jié)果為:'<em>This</em> is <em>it</em>!'

5,其他有趣的標(biāo)準(zhǔn)模塊

模塊名稱描述
argparse在UNIX中,運(yùn)行命令行程序時(shí)常常需要指定各種選項(xiàng)(開關(guān)),Python解釋器就是這樣的典范。這些選項(xiàng)都包含在sys.argv中,但要正確地處理它們絕非容易。模塊argparse使得提供功能齊備的命令行界面易如反掌。
cmd這個(gè)模塊讓你能夠編寫類似于Python交互式解釋器的命令行解釋器。你可定義命令,讓用戶能夠在提示符下執(zhí)行它們。或許可使用這個(gè)模塊為你編寫的程序提供用戶界面?
csvCSV指的是逗號分隔的值(comma-seperated values),很多應(yīng)用程序(如很多電子表格程序和數(shù)據(jù)庫程序)都使用這種簡單格式來存儲表格數(shù)據(jù)。這種格式主要用于在不同的程序之間交換數(shù)據(jù)。模塊csv讓你能夠輕松地讀寫CSV文件,它還以非常透明的方式處理CSV格式的一些棘手部分。
datetime如果模塊time不能滿足你的時(shí)間跟蹤需求,模塊datetime很可能能夠滿足。datetime支持特殊的日期和時(shí)間對象,并讓你能夠以各種方式創(chuàng)建和合并這些對象。相比于模塊time,模塊datetime的接口在很多方面都更加直觀。
difflib這個(gè)庫讓你能夠確定兩個(gè)序列的相似程度,還讓你能夠從很多序列中找出與指定序列最為相似的序列。例如,可使用difflib來創(chuàng)建簡單的搜索程序。
enum枚舉類型是一種只有少數(shù)幾個(gè)可能取值的類型。很多語言都內(nèi)置了這樣的類型,如果你在使用Python時(shí)需要這樣的類型,模塊enum可提供極大的幫助。
functools這個(gè)模塊提供的功能是,讓你能夠在調(diào)用函數(shù)時(shí)只提供部分參數(shù)(部分求值,partial evaluation),以后再填充其他的參數(shù)。在Python 3.0中,這個(gè)模塊包含filter和reduce。
hashlib使用這個(gè)模塊可計(jì)算字符串的小型“簽名”(數(shù))。計(jì)算兩個(gè)不同字符串的簽名時(shí),幾乎可以肯定得到的兩個(gè)簽名是不同的。你可使用它來計(jì)算大型文本文件的簽名,這個(gè)模塊在加密和安全領(lǐng)域有很多用途。
itertools包含大量用于創(chuàng)建和合并迭代器(或其他可迭代對象)的工具,其中包括可以串接可迭代對象、創(chuàng)建返回?zé)o限連續(xù)整數(shù)的迭代器(類似于range,但沒有上限)、反復(fù)遍歷可迭代對象以及具有其他作用的函數(shù)。
logging使用print語句來確定程序中發(fā)生的情況很有用。要避免跟蹤時(shí)出現(xiàn)大量調(diào)試輸出,可將這些信息寫入日志文件中。這個(gè)模塊提供了一系列標(biāo)準(zhǔn)工具,可用于管理一個(gè)或多個(gè)中央日志,它還支持多種優(yōu)先級不同的日志消息。
statistics計(jì)算一組數(shù)的平均值并不那么難,但是要正確地獲得中位數(shù),以確定總體標(biāo)準(zhǔn)偏差和樣本標(biāo)準(zhǔn)偏差之間的差別,即便對于偶數(shù)個(gè)元素來說,也需要費(fèi)點(diǎn)心思。在這種情況下,不要手工計(jì)算,而應(yīng)使用模塊statistics!
timeit模塊timeit(和配套的命令行腳本)是一個(gè)測量代碼段執(zhí)行時(shí)間的工具。這個(gè)模塊暗藏玄機(jī),度量性能時(shí)你可能應(yīng)該使用它而不是模塊time。
profile模塊profile(和配套模塊pstats)可用于對代碼段的效率進(jìn)行更全面的分析。
trace模塊trace可幫助你進(jìn)行覆蓋率分析(即代碼的哪些部分執(zhí)行了,哪些部分沒有執(zhí)行),這在編寫測試代碼時(shí)很有用。

小結(jié)

概念解釋
模塊模塊基本上是一個(gè)子程序,主要作用是定義函數(shù)、類和變量等。模塊包含測試代碼時(shí),應(yīng)將這些代碼放在一條檢查name == 'main’的if語句中。如果模塊位于環(huán)境變量PYTHONPATH包含的目錄中,就可直接導(dǎo)入它;要導(dǎo)入存儲在文件foo.py中的模塊,可使用語句import foo。
包不過是包含其他模塊的模塊。包是使用包含文件__init__.py的目錄實(shí)現(xiàn)的。
探索模塊在交互式解釋器中導(dǎo)入模塊后,就可以眾多不同的方式對其進(jìn)行探索,其中包括使用dir、查看變量__all__以及使用函數(shù)help。文檔和源代碼也是獲取信息和洞見的極佳來源。
標(biāo)準(zhǔn)庫Python自帶多個(gè)模塊,統(tǒng)稱為標(biāo)準(zhǔn)庫。
標(biāo)準(zhǔn)庫名稱介紹
sys這個(gè)模塊讓你能夠訪問多個(gè)與Python解釋器關(guān)系緊密的變量和函數(shù)。
os這個(gè)模塊讓你能夠訪問多個(gè)與操作系統(tǒng)關(guān)系緊密的變量和函數(shù)。
fileinput這個(gè)模塊讓你能夠輕松地迭代多個(gè)文件或流的內(nèi)容行。
sets、heapq和deque這三個(gè)模塊提供了三種很有用的數(shù)據(jù)結(jié)構(gòu)。內(nèi)置類型set也實(shí)現(xiàn)了集合。
time這個(gè)模塊讓你能夠獲取當(dāng)前時(shí)間、操作時(shí)間和日期以及設(shè)置它們的格式。
random這個(gè)模塊包含用于生成隨機(jī)數(shù),從序列中隨機(jī)地選擇元素,以及打亂列表中元素的函數(shù)。
shelve這個(gè)模塊用于創(chuàng)建永久性映射,其內(nèi)容存儲在使用給定文件名的數(shù)據(jù)庫中。
re支持正則表達(dá)式的模塊。

本章節(jié)介紹的新函數(shù)

函數(shù)描述
dir(obj)返回一個(gè)按字母順序排列的屬性名列表
help([obj])提供交互式幫助或有關(guān)特定對象的幫助信息
imp.reload(module)返回已導(dǎo)入的模塊的重載版本

總結(jié)

以上是生活随笔為你收集整理的第十章 开箱即用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 99一级片| 欧美一区二区高清视频 | 国产精品人妻一区二区三区 | 91精品毛片 | 国产亚洲精品久久久久久无几年桃 | 伊人三级| 欧美一a| 日韩欧美福利视频 | 老司机午夜性大片 | 91精品国产91久久久久久 | 精品久久在线观看 | 国产在线观看免费av | 国产精品美女久久久免费 | 国产xxx在线观看 | 伊人久久色 | 日本大尺度做爰呻吟 | 91蜜桃婷婷狠狠久久综合9色 | 熟女一区二区三区四区 | 黄色一级大片在线免费看产 | 91视频高清 | 91xxx在线观看 | 超碰2| 六月婷婷av | 国产精品色综合 | 男女操操视频 | 中文字幕日韩一区二区 | 爱情岛黄色 | 成人黄色激情 | 中文字幕免 | 激情视频区 | 中文永久免费观看 | heyzo在线播放 | 亚洲婷婷在线观看 | 久久久久人妻精品一区二区三区 | 天天干,天天干 | 亚洲91网| 日韩乱码人妻无码中文字幕 | 大学生三级中国dvd 日韩欧美一区二区区 | 色玖玖综合 | 另类激情亚洲 | www.狠狠艹 | 久久99精品久久久久久国产越南 | 天天夜夜草 | 狠狠躁夜夜躁人 | 经典杯子蛋糕日剧在线观看免费 | 国产精品美女www爽爽爽视频 | 国产露脸无套对白在线播放 | va视频在线 | 中国性xxx | 日本三级生活片 | 精品无码免费视频 | 国内成人在线 | 欧美黄在线观看 | 蜜臀99久久精品久久久久久软件 | 日韩日韩日韩日韩日韩 | 福利影院在线观看 | 97人人看| 国产三级观看 | www.一起操 | 欧美在线视频网站 | 亚洲欧美国产另类 | 日本综合在线 | 男人天堂视频网 | 亚洲免费视 | 刘亦菲毛片一区二区三区 | 国产又粗又猛又爽又黄的视频在线观看动漫 | 亚洲一二三不卡 | 人人综合网 | 手机看片1024日韩 | 国产精品久久久久久久久久小说 | 老湿机69福利区午夜x片 | 久久欧美 | 久久综合99 | 五月激情在线观看 | 97精品国产露脸对白 | 麻豆成人免费视频 | 99在线视频播放 | 国产专区av| 国产精品你懂得 | 国产酒店自拍 | 久久精品aⅴ无码中文字字幕重口 | 一本在线免费视频 | av在线入口 | 男女日批视频 | 日韩精品极品 | 一级黄色av| 97超碰在 | 台湾综合色 | 成人综合区 | 影音先锋丝袜制服 | 国产对白羞辱绿帽vk | 91视频免费看片 | 国产精品高潮呻吟视频 | 尤物影院在线观看 | 91看黄| 国语对白做受69按摩 | 国产黄色片免费 | 亚洲伦理中文字幕 | 人人看人人看 |