a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 學院 > 操作系統 > 正文

Python-day4

2024-06-28 16:00:47
字體:
來源:轉載
供稿:網友

1.裝飾器

解:本質上是函數,在語法上和普通的函沒有區別(裝飾其他函數,為其他函數添加附加功能) 原則1:不能修改被裝飾的函數的源代碼 原則2:不能修改被裝飾的函數的調用方式 注:對于被裝飾器裝飾的函數而言,裝飾器的透明,完全感知不到其的存在

裝飾器知識儲備: 1.函數即“變量” 2.高階函數 3.嵌套函數

高階函數+嵌套函數====》》》》裝飾器

函數的理解: 注:其實在Python中,函數也是“變量”,在計算機中,函數就是將函數體(即函數內容)賦值給一個名叫xxx(函數名字)的變量,然后引用的時候xxx(),變量則是直接引用變量名字就可以了,其中函數體在內存中存在形式只是一堆字符串,而且如果變量x=1,在內存中會將1這個值實實在在的存放下來,如果又有y=x,那么在內存中1的值將被二次引用,只有當x,y都不存在了那么1占用的地址空間才會被內存釋放,Python的內存回收機制就是這種原理

1.函數講解1:

def one(): PRint("This is one scripts!") two()def two(): print("This is two scripts!")one()###################################This is one scripts!This is two scripts!def two(): print("This is two scripts!")def one(): print("This is one scripts!") two()one()########################################This is one scripts!This is two scripts!

注:注意以上兩端函數的定義以及引用,其實沒有本質上的區別,為什么呢?因為每當Python讀取函數函數對應的函數體時,這時內存已經記錄了這段函數體的地址,如果發現函數體里面也引用了函數,那么就會去查這個函數對應的函數體有沒有存在于內存中,如果有就去查相應的“門牌號”——函數名字,注意僅僅是在函數定義時函數嵌套函數的后者定義的順序是沒有限制的,只要存在那么Python就可以找得到被嵌套函數的函數體存在于內存何處以及相應的“門牌號”——函數名字

高階函數

1.把一個函數名當做實參傳遞給另外一個函數

2.返回值包含函數名

例1:

#!/usr/bin/env python3# this is tandabin scripts!!def test(here): print(here) here() org()def org(): print("asd")test(org)#########################################<function org at 0x0000000000B3E840>asdasd#############################################org=here,門牌號相同,相當于org()的函數體也同時賦值,所以誕生了這么個引用here()

注:當高階函數的參數賦值被一個函數名賦值,那么這個參數本身就已經是個函數了,所以會出現以上的結果,記住不管是here,還是org都只是“函數名”,記錄在內存中的內存地址

例2:

#!/usr/bin/env python3# this is tandabin scripts!!import timedef test(here): start_time = time.time() here() stop_time = time.time() print("Script time %s"% (stop_time-start_time))def org(): time.sleep(3) print("asd")test(org)

注:以上的做法就有點類似裝飾器的概念,可以通過在裝飾器函數體中加入定時的內容去計算被裝飾函數的運行時間,滿足裝飾器條件1中的“不修改原函數的源代碼”,但是會發現調用的方式變了,不符合裝飾器條件2中的“不修改調用方式”

例3:

#!/usr/bin/env python3# this is tandabin scripts!!import timedef org(): time.sleep(3) print("in the org")def test(here): print(here) return hereorg = test(org)org()

注:以上是根據返回值調用函數實現裝飾器的做法,而且解決了在既不修改函數源代碼的情況下還實現了不修改函數的調用方式就能起到裝飾器的作用,呈現函數原有的功能并且添加新的輸出

例4:

#!/usr/bin/env python3# this is tandabin scripts!!import timedef one(): print("one") def two(): print("two") two()one()#############################onetwo

注:函數中嵌套聲明函數,這叫嵌套函數,但是被嵌套的函數相當于局部變量,不可以在外界進行調用,只能被主函數進行調用

例5:

#!/usr/bin/env python3# this is tandabin scripts!!import timedef timer(func): def deco(): start_time = time.time() func() stop_time = time.time() print("Func time: %s"% (stop_time-start_time)) return decodef test1(): time.sleep(3) print("test1")def test2(): time.sleep(3) print("test2")test1 = timer(test1)test1()test2 = timer(test2)test2()################################test1Func time: 3.000171661376953test2Func time: 3.000171422958374

注:高階函數+嵌套函數+不修改函數源代碼+不修改調用方式完成裝飾器功能,其中裝飾器函數是將timer是將test1,test2作為參數傳入,然后執行裝飾器函數時往下執行嵌套函數deco,deco函數中的功能是計算func函數的執行時間(func是作為參數傳入的,由于test1,test2的傳入,所以func=test1,func=test2,而且函數名其實在內存中就是變量,故而可以通過func()方式調用函數體),當deco函數執行完后,返回上一次發現timer函數的執行語句其實就是return返回deco函數的返回結果,也就是對應的內存地址(門牌號),然后調用的時候通過將timer(test1)的結果(因為timer函數執行完就只是返回deco的內存地址)賦值給test1函數變量名,修改test1的函數體,然后test1()調用,就可以做到裝飾器的作用,一來正常執行test1的函數,而來增加了計算test1函數的執行時間

例6:
#!/usr/bin/env python3# this is tandabin scripts!!import timedef timer(func): def deco(): start_time = time.time() func() stop_time = time.time() print("Func time: %s"% (stop_time-start_time)) return deco@timerdef test1(): time.sleep(3) print("test1")@timerdef test2(): time.sleep(3) print("test2")test1()test2()

注:@timer的作用是替代上文的test1 = timer(test1)

例7:

#!/usr/bin/env python3# this is tandabin scripts!!import timedef timer(func): def deco(*args,**kwargs): start_time = time.time() func(*args,**kwargs) stop_time = time.time() print("Func time: %s"% (stop_time-start_time)) return deco@timer# 等于test1 = timer(test1) = deco 由于裝飾器函數timer的函數返回結果deco的內存地址(“門牌號”)def test1(): time.sleep(3) print("test1")@timer# 等于test2 = timer(test2) = decodef test2(name,age): time.sleep(3) print("test2 and %s and %s"% (name,age))test1()test2("charlie",21)

注:如果在test2中想引用參數,只需要在裝飾器函數中的嵌套函數deco中加入形參以及func參數加入形參就可以實現,由于裝飾器函數的返回結果就是deco(deco函數的函數名,即內存地址),所以test2()等于deco(),test2加入參數也只需要在deco中加入參數即可,如上訴例子,在裝飾器引入參數并不會影響test1函數的調用,可以調入參數也可以不調入參數,用*ages以及**kwargs就可以實現

例8:

#!/usr/bin/env python3# this is tandabin scripts!!import os,getpassusername = "charlie"passWord = "abc123"def first(func): def verify(*args,**kwargs): fulluser = input("Please input your user: ") fullpassword = input("Please input your pass: ") if fulluser == username and fullpassword == password: print("verify successfully!!") func(*args,**kwargs) else: exit("Input invalid!") return verifydef index(): print("welcome to index!!!")@firstdef home(): print("welcome to home!!!")@firstdef second(): print("welcome to second!!!")index()home()second()############################################welcome to index!!!Please input your user: charliePlease input your pass: abc123verify successfully!!welcome to home!!!Please input your user: charliePlease input your pass: abc123verify successfully!!welcome to second!!!############################################welcome to index!!!Please input your user: charliePlease input your pass: abc123verify successfully!!welcome to home!!!Please input your user: charasPlease input your pass: 123Input invalid!

注:常見的網站次級頁面登錄模擬裝飾器的應用場景

裝飾器范例終極版:

#!/usr/bin/env python3# this is tandabin scripts!!username = "charlie"password = "abc123"def first(verify_type): print("verify type: ",verify_type) def twice(func): def verify(*args,**kwargs): print("verify type: ",*args,**kwargs) fulluser = input("Please input your user: ") fullpassword = input("Please input your pass: ") if verify_type == "local": if fulluser == username and fullpassword == password: print("verify successfully!!") print(*args,**kwargs) res = func(*args,**kwargs) print(res) else: exit("Input invalid!") elif verify_type == "ldap": print("without ldap!!!") return verify return twicedef index(): print("welcome to index!!!")@first(verify_type = "local")def home(*args,**kwargs): print("welcome to home!!!") return "from home"@first(verify_type = "ldap")def second(): print("welcome to second!!!")index()home("CR",7,"9400W","the best man")second()#################################################verify type: localverify type: ldapwelcome to index!!!verify type: CR 7 9400W the best manPlease input your user: charliePlease input your pass: abc123verify successfully!!CR 7 9400W the best manwelcome to home!!!from homeverify type: Please input your user: charliePlease input your pass: abc123without ldap!!!

注:通過不同驗證方式開啟不用的校驗登錄到不同頁面,三級嵌套函數的裝飾器可以實現這一個功能,通過將裝飾器以函數的形式調用,并且往里面加入參數,然后將裝飾器裝飾的函數時本來就有的一個參數func通過往下壓一層到二級嵌套函數twice中導入func,然后接下來的引用就和上文一樣,通過“偷梁換柱”將原本外界調用的主函數以裝飾器函數中對verify的調用而替換,并且加入if、else的判斷從而可以實現功能新添,而且外界調用函數時還可以添加不限制個數的參數到主函數中去掉用,然后被加入的函數又有同時在裝飾器中被引用,如果不添加參數也不影響實際的用戶體驗效果

2.列表生成式:

print([ i*2 for i in range(10)])#####################################[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

注:節省代碼,快速生成列表

3.生成器:

注:通過列表生成式,我們可以直接創建一個列表。但是,受到內存限制,列表容量肯定是有限的。而且,創建一個包含100萬個元素的列表,不僅占用很大的存儲空間,如果我們僅僅需要訪問前面幾個元素,那后面絕大多數元素占用的空間都白白浪費了。

所以,如果列表元素可以按照某種算法推算出來,那我們是否可以在循環的過程中不斷推算出后續的元素呢?這樣就不必創建完整的list,從而節省大量的空間。在Python中,這種一邊循環一邊計算的機制,稱為生成器:generator。

要創建一個generator,有很多種方法。第一種方法很簡單,只要把一個列表生成式的[]改成(),就創建了一個generator:

3.1.范例1:

b = (i*2 for i in range(10))print(b)##############################<generator object <genexpr> at 0x00000000007C69E8>

注:生成器最基本用法

3.2.范例2:

b = (i*2 for i in range(10))for i in b: print(i)#############################024681012141618

注:利用生成器的方法生成100W個元素的效率遠比定義100W個元素的速度快

3.3范例3:

b = [i*2 for i in range(10000000)]print(b)#######################################略........................2, 3860354, 3860356, 3860358, 3860360, 3860362, 3860364, 3860366, 3860368, 3860370, 3860372, 3860374, 3860376, 3860378, 3860380, 3860382, 3860384, 3860386, 3860388, 3860390, 3860392, 3860394, 3860396, 3860398, 3860400, 3860402, 3860404, 3860406, 3860408, 3860410, 3860412, 3860414, 3860416, 3860418, 3860420, 3860422, 3860424, 3860426, 3860428, 3860430, 3860432, 3860434, 3860436, 3860438, 3860440, 3860442, 3860444, 3860446, 3860448, 3860450, 3860452, 3860454, 3860456, 3860458, 3860460, 3860462, 3860464, 3860466, 3860468, 3860470, 3860472, 3860474, 3860476, 3860478, 3860480, 3860482, 3860484, 3860486, 3860488, 3860490, 3860492, 3860494, 3860496, 3860498, 3860500, 3860502, 3860504, 3860506, 3860508, 3860510, 3860512, 3860514, 3860516, 3860518, 3860520, 3860522, 3860524, 3860526, 3860528, 3860530, 3860532, 3860534, 3860536, 3860538, 3860540, 3860542, 3860544, 3860546, 3860548, 3860550, 3860552, 3860554, 3860556, 3860558, 3860560, 3860562, 3860564, 3860566, 3860568, 3860570, 3860572, 3860574, 3860576, 3860578, 3860580, 3860582, 3860584, 3860586, 3860588, 3860590, 3860592, 3860594, 3860596, 3860598, 3860600, 3860602, 3860604, 3860606, 3860608, 3860610, 3860612, 3860614, 3860616, 3860618, 3860620, 3860622, 3860624, 3860626, 3860628, 3860630, 3860632, 3860634, 3860636, 3860638, 3860640, 3860642, 3860644, 3860646, 3860648, 3860650, 3860652, 3860654, 3860656, 3860658, 3860660, 3860662, 3860664, 3860666, 3860668, 3860670, 3860672, 3860674, 3860676, 3860678, 3860680, 3860682, 3860684, 3860686, 3860688, 3860690, 3860692, 3860694, 3860696, 3860698, 3860700, 3860702, 3860704, 3860706, 3860708, 3860710, 3860712, 3860714, 3860716, 3860718, 3860720, 3860722, 3860724, 3860726, 3860728, 3860730, 3860732, 3860734, 3860736, 3860738, 3860740, 3860742, 3860744, 3860746, 3860748, 3860750, 3860752, 3860754#略.............c = (i*2 for i in range(10000000))for i in c: print(i)#######################################略................296428296430296432296434296436296438296440296442296444296446296448296450296452296454(Ctrl C取消)..............

注:如上圖所示,使用生成器的效果是列表的生成讀取以及內存占用只會到循環的最后一次,什么時候Ctrl C就只是占用從開始到中斷的這部分的內存空間,如果是使用列表的定義,不管循環到第幾層,內存處理數據都會讀取整個列表的數據以及每個數據占用一個內存空間,然后才做邏輯處理,兩種方式體現了內存的優化差異性

注:生成器只有在調用時才會生成相應的數據,并且只記錄當前的值,循環過的前面的值生成器是不會記錄的,換言之就是循環過的就“沒”了,只可以繼續往后循環,不可以回退,而且不能跨步循環,只能一個個的往下一個值循環,這樣的目的是為了最大程度的節省內存。

3.4函數生成器斐波那契:

def fib(max): a = 0 b = 1 count = 0 while count < max: print(b) a = b b = a + b count+=1 return 'False!'fib(10)##################################1248163264128256512#################################################def fib(max): a = 0 b = 1 count = 0 while count<max: print(b) a,b = b,a+b count+=1 return 'False'fib(10)#####################################################11235813213455

注:注意兩種函數寫法的不同輸出結果,下面一種的賦值方式相當于; t = (b, a + b) # t是一個tuple a = t[0] b = t[1] 值不會隨著上面方式改變而改變,這里避免混淆!

3.5函數生成器真正實現方式:

#!/usr/bin/env python3# this is tandabin scripts!!def fib(max): a = 0 b = 1 count = 0 while count<max: yield b a,b = b,a+b count+=1 return 'False'f = fib(10)print(f.__next__())print(f.__next__())print("CR7".center(50,"="))print(f.__next__())print(f.__next__())print("start for".center(50,"="))for i in f: print(i)###############################################11=======================CR7========================23====================start for=====================5813213455

注:將print換成yield就是函數變成生成器的做法,而且生成器的好處就是可以隨時控制循環到某個特定位置時跳出來去執行其他的動作,執行完之后再回去繼續后面的循環!!!

3.6函數生成器真正實現方式2:

#!/usr/bin/env python3# this is tandabin scripts!!def fib(max): a = 0 b = 1 count = 0 while count<max: yield b a,b = b,a+b count+=1 return 'Are you kidding me?'f = fib(6)while True: try: x = next(f) print('f:',x) except StopIteration as e: print('StopIteration return value:',e.value) break#######################################################f: 1f: 1f: 2f: 3f: 5f: 8StopIteration return value: Are you kidding me?

注:當通過for循環輸出生成器的時候,return結果是沒有的,不要問我為什么,但是當用while循環的時候,就可以利用StopIteration報錯的方式檢測,當時錯誤的時候抓取關鍵字然后讓循環結束,也就是說函數生成器的return相當于是拿來排錯的!

3.7簡單協程用法1:

import timedef consumer(name): print("%s 準備吃包子啦!" %name) while True: baozi = yield print("包子[%s]來了,被[%s]吃了!" %(baozi,name))f = consumer("charlie")f.__next__()f.__next__()f.send("豬肉包子")#############################################################charlie 準備吃包子啦!包子[None]來了,被[charlie]吃了!包子[豬肉包子]來了,被[charlie]吃了!

注:next方法和send方法唯一的區別是,都是調用yield并且返回結果,但是send會將值傳入yield再返回,而next方法只調用yield并不會傳值返回

3.8多任務并行執行:

import timedef consumer(name): print("%s 準備吃包子啦!" %name) while True: baozi = yield print("包子[%s]來了,被[%s]吃了!" %(baozi,name))def producer(name): c = consumer('charlie') c2 = consumer('bob') c.__next__() c2.__next__() print("老子開始準備做包子啦!") for i in range(5): time.sleep(1) print("做了2個包子!") c.send(i) c2.send(i)producer("CR7")#############################################################charlie 準備吃包子啦!bob 準備吃包子啦!老子開始準備做包子啦!做了2個包子!包子[0]來了,被[charlie]吃了!包子[0]來了,被[bob]吃了!做了2個包子!包子[1]來了,被[charlie]吃了!包子[1]來了,被[bob]吃了!做了2個包子!包子[2]來了,被[charlie]吃了!包子[2]來了,被[bob]吃了!做了2個包子!包子[3]來了,被[charlie]吃了!包子[3]來了,被[bob]吃了!做了2個包子!包子[4]來了,被[charlie]吃了!包子[4]來了,被[bob]吃了!

注:nginx之所以速度快就是因為采用了以上的單線程多協程的工作原理,提高執行效率

迭代器:

我們知道,可以直接作用于for循環的數據類型有以下幾種:

一類是集合數據類型,如list、tuple、dict、set、str等等;

一類是generator,包括生成器和帶yield的generator function

這些可以直接作用于for循環對象稱為可迭代對象:iterable

可以使用isinstance()判斷一個對象是否是iterable對象:

3.9判斷數據類型是否是可迭代對象:

>>> isinstance([],Iterable)True>>> isinstance({},Iterable)True>>> isinstance((x for x in range(10)),Iterable)True>>> isinstance('abc',Iterable)True>>> isinstance(100,Iterable)False

注:而生成器不但可以作用于for循環,還可以被next()函數不斷調用并返回下一個值,直到最后拋出StopIteration錯誤表示無法繼續返回下一個值了

*可以被next()函數調用并不斷返回下一個值的對象稱為迭代器:Iterator。

:值得注意,生成器都是迭代器對象,但是可迭代對象不一定是迭代器

3.10判斷a有哪些方法可以調用:

>>> a = [1,2,3]>>> dir(a)['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__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']>>>

3.11利用iter方法將列表轉換成迭代器:

>>> a = [1,2,3]>>> a[1, 2, 3]>>> iter(a)<list_iterator object at 0x7f05445f9ba8>>>> p = iter(a)>>> p.__next__()1>>> p.__next__()2>>> p.__next__()3>>> p.__next__()Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration

注:把list、dict、str等Iterable變成Iterator可以使用iter()函數

你可能會問,為什么list、dict、str等數據類型不是Iterator?

這是因為Python的Iterator對象表示的是一個數據流,Iterator對象可以被next()函數調用并不斷返回下一個數據,直到沒有數據時拋出StopIteration錯誤。可以把這個數據流看做是一個有序序列,但我們卻不能提前知道序列的長度,只能不斷通過next()函數實現按需計算下一個數據,所以Iterator的計算是惰性的,只有在需要返回下一個數據時它才會計算。

Iterator甚至可以表示一個無限大的數據流,例如全體自然數。而使用list是永遠不可能存儲全體自然數的。

小結

凡是可作用于for循環的對象都是Iterable類型;

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

集合數據類型如list、dict、str等是Iterable但不是Iterator,不過可以通過iter()函數獲得一個Iterator對象。

Python的for循環本質上就是通過不斷調用next()函數實現的,例如:

4.1內置函數all

print(all([1,2,3]))print(all([0,2,3]))#############################TrueFalse

注:利用內置函數all判斷一個可迭代對象是否為“真”,值得注意的是在計算機中“非”“0”即為“真”

4.2內置函數any

print(any([0,1,0]))print(any([]))###########################TrueFalse

注:和all的區別是,如果判斷的對象是有一個可迭代對象,那么就會返回“真”

4.3內置函數bin

>>> bin(4)'0b100'>>> bin(255)'0b11111111'>>> bin(223)'0b11011111'

注:數字的二進制轉換

4.4內置函數bool

>>> bool<class 'bool'>>>> bool(0)False>>> bool(1)True>>> bool([1,2,3])True>>> bool([])False

注:判斷真假

4.5內置函數callable

def a(): print("Yes")print(callable([]))print(callable(a))######################FalseTrue

注:判斷一個對象是否可以被調用,即加上()

4.6內置函數chr,ord

>>> chr(123)'{'>>> chr(100)'d'>>> ord("b")98>>> ord("d")100>>>

注:輸出ASCII碼數字對應的值,ord用法正好相反

4.7匿名函數:

calc = lambda n:print(n)calc(5)############################5

注:匿名函數的用法,而且匿名函數是只調用一次程序就回收這部分的內存空間,即立即釋放

4.8匿名函數結合filter方法:

res = filter(lambda n:n>5,range(10))for i in res: print(i)############################################6789

注:fileter的作用是把合格的結果過濾出來

4.9匿名函數結合map方法:

res = map(lambda n:n*n,range(10))for i in res: print(i)####################################0149162536496481

注:map的作用是將每個數字都匹配條件然后輸出

4.10reduce函數用法

import functoolsres = functools.reduce( lambda x,y:x+y,range(10))print(res)####################################################45

注:將每個循環的結果都加起來算出最終的結果

4.11globals函數

>>> print(globals()){'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__doc__': None, '__builtins__': <module 'builtins' (built-in)>, '__package__': None, '__name__': '__main__', '__spec__': None}>>>

注:輸出當前的全局變量

4.12divmod函數

>>> divmod(5,2)(2, 1)>>> divmod(10,2)(5, 0)

注:輸出“商”取“余”

4.13只讀集合函數

>>> a = set([1,1,2,3,4,3])>>> a.add(123213121)>>> a{1, 2, 3, 4, 123213121}>>> a = frozenset([1,2,3,1,2,3,2])

注:frozenset相當于元組(只讀列表)的作用,不能修改等操作

4.14十六進制轉換

>>> hex(255)'0xff'>>> hex(25)'0x19'

4.15八進制轉換

>>> oct(10)'0o12'>>> oct(1)'0o1'>>> oct(2)'0o2'>>> oct(4)'0o4'>>> oct(5)'0o5'>>> oct(6)'0o6'>>> oct(7)'0o7'>>> oct(8)'0o10'

4.16n的n次方

>>> pow(2,8)256

4.17有序字典及排序

>>> a = {1:2,3:3,-5:1}>>> a{1: 2, 3: 3, -5: 1}>>> print(sorted(a.items())) [(-5, 1), (1, 2), (3, 3)]>>> print(sorted(a.items(),key=lambda x:x[1])) [(-5, 1), (1, 2), (3, 3)]

注:按照key培訓以及按照value排序

4.18zip“拉鏈”函數:

a = [1,2,3,4,5,6]b = ['a','b','c','d','e','f','g']for i in zip(a,b): print(i)#########################################(1, 'a')(2, 'b')(3, 'c')(4, 'd')(5, 'e')(6, 'f')

注:如果有一方數據少了,那么合并數據時只會合并少的那方的個數

4.19引入自定義函數

__import__('xxx')

注:如果想引進自己寫好的函數或者某個功能,但是只記得名字,就用這種方式導入


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 国产精品久久久久久婷婷天堂 | 综合激情视频 | 亚洲精品中文字幕 | 国产欧美精选 | 一区二区三区在线 | www..99热 | 日本a区 | 久久久tv| 久久国产乱子伦精品免费午夜,浪货好紧 | 日韩成人在线观看 | 国产精品久久久久久久久久妞妞 | 久久久久无码国产精品一区 | 久久精品a级毛片 | 亚洲免费一 | aaa在线| 先锋资源av在线 | 黄色网页免费观看 | 欧美精品第十页 | 欧美精品在线观看免费 | 极品少妇xxxxⅹ另类 | 日韩久久综合 | 国产精品不卡视频 | 免费一区在线 | 成人亚洲 | 欧美日韩在线免费观看 | 国产精品一区二区在线播放 | 欧美久久a | 91精品久久久久久久99 | 一区二区三区视频免费在线观看 | 日韩精品1区 | 日本在线天堂 | 中文字幕av第一页 | 玖玖成人 | 亚洲欧美日韩在线一区 | 日韩欧美精品区 | 国产日韩精品在线观看 | 国产在线小视频 | 亚洲乱码一区二区 | 欧美一区二区三区视频 | 毛片一区二区三区 | 99视频在线 |