精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

詳解Python的裝飾器

開發(fā) 后端
Python中的裝飾器是你進入Python大門的一道坎,不管你跨不跨過去它都在那里。裝飾器本質(zhì)上是一個Python函數(shù),它可以讓其他函數(shù)在不需要做任何代碼變動的前提下增加額外功能,裝飾器的返回值也是一個函數(shù)對象。概括的講,裝飾器的作用就是為已經(jīng)存在的函數(shù)或?qū)ο筇砑宇~外的功能。

[[174941]]

Python中的裝飾器是你進入Python大門的一道坎,不管你跨不跨過去它都在那里。

為什么需要裝飾器

我們假設(shè)你的程序?qū)崿F(xiàn)了say_hello()和say_goodbye()兩個函數(shù)。

  1. def say_hello(): 
  2.     print "hello!" 
  3.      
  4. def say_goodbye(): 
  5.     print "hello!"  # bug here 
  6.  
  7. if __name__ == '__main__'
  8.     say_hello() 
  9.     say_goodbye()  

但是在實際調(diào)用中,我們發(fā)現(xiàn)程序出錯了,上面的代碼打印了兩個hello。經(jīng)過調(diào)試你發(fā)現(xiàn)是say_goodbye()出錯了。老板要求調(diào)用每個方法前都要記錄進入函數(shù)的名稱,比如這樣:

  1. [DEBUG]: Enter say_hello() 
  2. Hello! 
  3. [DEBUG]: Enter say_goodbye() 
  4. Goodbye!  

好,小A是個畢業(yè)生,他是這樣實現(xiàn)的。

  1. def say_hello(): 
  2.     print "[DEBUG]: enter say_hello()" 
  3.     print "hello!" 
  4.  
  5. def say_goodbye(): 
  6.     print "[DEBUG]: enter say_goodbye()" 
  7.     print "hello!" 
  8.  
  9. if __name__ == '__main__'
  10.     say_hello() 
  11.     say_goodbye()  

很low吧? 嗯是的。小B工作有一段時間了,他告訴小A可以這樣寫。

  1. def debug(): 
  2.     import inspect 
  3.     caller_name = inspect.stack()[1][3] 
  4.     print "[DEBUG]: enter {}()".format(caller_name)    
  5.  
  6. def say_hello(): 
  7.     debug() 
  8.     print "hello!" 
  9.  
  10. def say_goodbye(): 
  11.     debug() 
  12.     print "goodbye!" 
  13.  
  14. if __name__ == '__main__'
  15.     say_hello() 
  16.     say_goodbye()  

是不是好一點?那當然,但是每個業(yè)務(wù)函數(shù)里都要調(diào)用一下debug()函數(shù),是不是很難受?萬一老板說say相關(guān)的函數(shù)不用debug,do相關(guān)的才需要呢?

那么裝飾器這時候應(yīng)該登場了。

裝飾器本質(zhì)上是一個Python函數(shù),它可以讓其他函數(shù)在不需要做任何代碼變動的前提下增加額外功能,裝飾器的返回值也是一個函數(shù)對象。它經(jīng)常用于有切面需求的場景,比如:插入日志、性能測試、事務(wù)處理、緩存、權(quán)限校驗等場景。裝飾器是解決這類問題的***設(shè)計,有了裝飾器,我們就可以抽離出大量與函數(shù)功能本身無關(guān)的雷同代碼并繼續(xù)重用。

概括的講,裝飾器的作用就是為已經(jīng)存在的函數(shù)或?qū)ο筇砑宇~外的功能。

怎么寫一個裝飾器

在早些時候 (Python Version < 2.4,2004年以前),為一個函數(shù)添加額外功能的寫法是這樣的。

  1. def debug(func): 
  2.     def wrapper(): 
  3.         print "[DEBUG]: enter {}()".format(func.__name__) 
  4.         return func() 
  5.     return wrapper 
  6.  
  7. def say_hello(): 
  8.     print "hello!" 
  9.  
  10. say_hello = debug(say_hello)  # 添加功能并保持原函數(shù)名不變  

上面的debug函數(shù)其實已經(jīng)是一個裝飾器了,它對原函數(shù)做了包裝并返回了另外一個函數(shù),額外添加了一些功能。因為這樣寫實在不太優(yōu)雅,在后面版本的Python中支持了@語法糖,下面代碼等同于早期的寫法。

  1. def debug(func): 
  2.     def wrapper(): 
  3.         print "[DEBUG]: enter {}()".format(func.__name__) 
  4.         return func() 
  5.     return wrapper 
  6.  
  7. @debug 
  8. def say_hello(): 
  9.     print "hello!"  

這是最簡單的裝飾器,但是有一個問題,如果被裝飾的函數(shù)需要傳入?yún)?shù),那么這個裝飾器就壞了。因為返回的函數(shù)并不能接受參數(shù),你可以指定裝飾器函數(shù)wrapper接受和原函數(shù)一樣的參數(shù),比如:

  1. def debug(func): 
  2.     def wrapper(something):  # 指定一毛一樣的參數(shù) 
  3.         print "[DEBUG]: enter {}()".format(func.__name__) 
  4.         return func(something) 
  5.     return wrapper  # 返回包裝過函數(shù) 
  6.  
  7. @debug 
  8. def say(something): 
  9.     print "hello {}!".format(something)  

這樣你就解決了一個問題,但又多了N個問題。因為函數(shù)有千千萬,你只管你自己的函數(shù),別人的函數(shù)參數(shù)是什么樣子,鬼知道?還好Python提供了可變參數(shù)*args和關(guān)鍵字參數(shù)**kwargs,有了這兩個參數(shù),裝飾器就可以用于任意目標函數(shù)了。

  1. def debug(func): 
  2.     def wrapper(*args, **kwargs):  # 指定宇宙無敵參數(shù) 
  3.         print "[DEBUG]: enter {}()".format(func.__name__) 
  4.         print 'Prepare and say...'
  5.         return func(*args, **kwargs) 
  6.     return wrapper  # 返回 
  7.  
  8. @debug 
  9. def say(something): 
  10.     print "hello {}!".format(something)  

至此,你已完全掌握初級的裝飾器寫法。

高級一點的裝飾器

帶參數(shù)的裝飾器和類裝飾器屬于進階的內(nèi)容。在理解這些裝飾器之前,***對函數(shù)的閉包和裝飾器的接口約定有一定了解。(參見http://betacat.online/posts/p...

帶參數(shù)的裝飾器

假設(shè)我們前文的裝飾器需要完成的功能不僅僅是能在進入某個函數(shù)后打出log信息,而且還需指定log的級別,那么裝飾器就會是這樣的。

  1. def logging(level): 
  2.     def wrapper(func): 
  3.         def inner_wrapper(*args, **kwargs): 
  4.             print "[{level}]: enter function {func}()".format( 
  5.                 level=level
  6.                 func=func.__name__) 
  7.             return func(*args, **kwargs) 
  8.         return inner_wrapper 
  9.     return wrapper 
  10.  
  11. @logging(level='INFO'
  12. def say(something): 
  13.     print "say {}!".format(something) 
  14.  
  15. # 如果沒有使用@語法,等同于 
  16. # say = logging(level='INFO')(say) 
  17.  
  18. @logging(level='DEBUG'
  19. def do(something): 
  20.     print "do {}...".format(something) 
  21.  
  22. if __name__ == '__main__'
  23.     say('hello'
  24.     do("my work" 

是不是有一些暈?你可以這么理解,當帶參數(shù)的裝飾器被打在某個函數(shù)上時,比如@logging(level='DEBUG'),它其實是一個函數(shù),會馬上被執(zhí)行,只要這個它返回的結(jié)果是一個裝飾器時,那就沒問題。細細再體會一下。

基于類實現(xiàn)的裝飾器

裝飾器函數(shù)其實是這樣一個接口約束,它必須接受一個callable對象作為參數(shù),然后返回一個callable對象。在Python中一般callable對象都是函數(shù),但也有例外。只要某個對象重載了__call__()方法,那么這個對象就是callable的。

  1. class Test(): 
  2.     def __call__(self): 
  3.         print 'call me!' 
  4.  
  5. t = Test() 
  6. t()  # call me  

像__call__這樣前后都帶下劃線的方法在Python中被稱為內(nèi)置方法,有時候也被稱為魔法方法。重載這些魔法方法一般會改變對象的內(nèi)部行為。上面這個例子就讓一個類對象擁有了被調(diào)用的行為。

回到裝飾器上的概念上來,裝飾器要求接受一個callable對象,并返回一個callable對象(不太嚴謹,詳見后文)。那么用類來實現(xiàn)也是也可以的。我們可以讓類的構(gòu)造函數(shù)__init__()接受一個函數(shù),然后重載__call__()并返回一個函數(shù),也可以達到裝飾器函數(shù)的效果。

  1. class logging(object): 
  2.     def __init__(self, func): 
  3.         self.func = func 
  4.  
  5.     def __call__(self, *args, **kwargs): 
  6.         print "[DEBUG]: enter function {func}()".format( 
  7.             func=self.func.__name__) 
  8.         return self.func(*args, **kwargs) 
  9. @logging 
  10. def say(something): 
  11.     print "say {}!".format(something)  

帶參數(shù)的類裝飾器

如果需要通過類形式實現(xiàn)帶參數(shù)的裝飾器,那么會比前面的例子稍微復(fù)雜一點。那么在構(gòu)造函數(shù)里接受的就不是一個函數(shù),而是傳入的參數(shù)。通過類把這些參數(shù)保存起來。然后在重載__call__方法是就需要接受一個函數(shù)并返回一個函數(shù)。

  1. class logging(object): 
  2.     def __init__(self, level='INFO'): 
  3.         self.level = level 
  4.          
  5.     def __call__(self, func): # 接受函數(shù) 
  6.         def wrapper(*args, **kwargs): 
  7.             print "[{level}]: enter function {func}()".format( 
  8.                 level=self.level
  9.                 func=func.__name__) 
  10.             func(*args, **kwargs) 
  11.         return wrapper  #返回函數(shù) 
  12.  
  13. @logging(level='INFO'
  14. def say(something): 
  15.     print "say {}!".format(something)  

內(nèi)置的裝飾器

內(nèi)置的裝飾器和普通的裝飾器原理是一樣的,只不過返回的不是函數(shù),而是類對象,所以更難理解一些。

@property

在了解這個裝飾器前,你需要知道在不使用裝飾器怎么寫一個屬性。

  1. def getx(self): 
  2.     return self._x 
  3.  
  4. def setx(self, value): 
  5.     self._x = value 
  6.      
  7. def delx(self): 
  8.    del self._x 
  9.  
  10. create a property 
  11. x = property(getx, setx, delx, "I am doc for x property") 

以上就是一個Python屬性的標準寫法,其實和Java挺像的,但是太羅嗦。有了@語法糖,能達到一樣的效果但看起來更簡單。

  1. @property 
  2. def x(self): ... 
  3.  
  4. # 等同于 
  5.  
  6. def x(self): ... 
  7. x = property(x)  

屬性有三個裝飾器:setter, getter, deleter ,都是在property()的基礎(chǔ)上做了一些封裝,因為setter和deleter是property()的第二和第三個參數(shù),不能直接套用@語法。getter裝飾器和不帶getter的屬性裝飾器效果是一樣的,估計只是為了湊數(shù),本身沒有任何存在的意義。經(jīng)過@property裝飾過的函數(shù)返回的不再是一個函數(shù),而是一個property對象。

  1. >>> property() 
  2. <property object at 0x10ff07940>  

@staticmethod,@classmethod

有了@property裝飾器的了解,這兩個裝飾器的原理是差不多的。@staticmethod返回的是一個staticmethod類對象,而@classmethod返回的是一個classmethod類對象。他們都是調(diào)用的是各自的__init__()構(gòu)造函數(shù)。

  1. class classmethod(object): 
  2.     ""
  3.     classmethod(function) -> method 
  4.     """     
  5.     def __init__(self, function): # for @classmethod decorator 
  6.         pass 
  7.     # ... 
  8. class staticmethod(object): 
  9.     ""
  10.     staticmethod(function) -> method 
  11.     ""
  12.     def __init__(self, function): # for @staticmethod decorator 
  13.         pass 
  14.     # ...  

裝飾器的@語法就等同調(diào)用了這兩個類的構(gòu)造函數(shù)。

  1. class Foo(object): 
  2.  
  3.     @staticmethod 
  4.     def bar(): 
  5.         pass 
  6.      
  7.     # 等同于 bar = staticmethod(bar)  

至此,我們上文提到的裝飾器接口定義可以更加明確一些,裝飾器必須接受一個callable對象,其實它并不關(guān)心你返回什么,可以是另外一個callable對象(大部分情況),也可以是其他類對象,比如property。

裝飾器里的那些坑

裝飾器可以讓你代碼更加優(yōu)雅,減少重復(fù),但也不全是優(yōu)點,也會帶來一些問題。

位置錯誤的代碼

讓我們直接看示例代碼。

  1. def html_tags(tag_name): 
  2.     print 'begin outer function.' 
  3.     def wrapper_(func): 
  4.         print "begin of inner wrapper function." 
  5.         def wrapper(*args, **kwargs): 
  6.             content = func(*args, **kwargs) 
  7.             print "<{tag}>{content}</{tag}>".format(tag=tag_name, content=content) 
  8.         print 'end of inner wrapper function.' 
  9.         return wrapper 
  10.     print 'end of outer function' 
  11.     return wrapper_ 
  12.  
  13. @html_tags('b'
  14. def hello(name='Toby'): 
  15.     return 'Hello {}!'.format(name
  16.  
  17. hello() 
  18. hello()  

在裝飾器中我在各個可能的位置都加上了print語句,用于記錄被調(diào)用的情況。你知道他們***打印出來的順序嗎?如果你心里沒底,那么***不要在裝飾器函數(shù)之外添加邏輯功能,否則這個裝飾器就不受你控制了。以下是輸出結(jié)果:

  1. begin outer function
  2. end of outer function 
  3. begin of inner wrapper function
  4. end of inner wrapper function
  5. <b>Hello Toby!</b> 
  6. <b>Hello Toby!</b>  

錯誤的函數(shù)簽名和文檔

裝飾器裝飾過的函數(shù)看上去名字沒變,其實已經(jīng)變了。

  1. def logging(func): 
  2.     def wrapper(*args, **kwargs): 
  3.         """print log before a function.""" 
  4.         print "[DEBUG] {}: enter {}()".format(datetime.now(), func.__name__) 
  5.         return func(*args, **kwargs) 
  6.     return wrapper 
  7.  
  8. @logging 
  9. def say(something): 
  10.     """say something""" 
  11.     print "say {}!".format(something) 
  12.  
  13. print say.__name__  # wrapper  

為什么會這樣呢?只要你想想裝飾器的語法糖@代替的東西就明白了。@等同于這樣的寫法。

  1. say = logging(say) 

logging其實返回的函數(shù)名字剛好是wrapper,那么上面的這個語句剛好就是把這個結(jié)果賦值給say,say的__name__自然也就是wrapper了,不僅僅是name,其他屬性也都是來自wrapper,比如doc,source等等。

使用標準庫里的functools.wraps,可以基本解決這個問題。

  1. from functools import wraps 
  2.  
  3. def logging(func): 
  4.     @wraps(func) 
  5.     def wrapper(*args, **kwargs): 
  6.         """print log before a function.""" 
  7.         print "[DEBUG] {}: enter {}()".format(datetime.now(), func.__name__) 
  8.         return func(*args, **kwargs) 
  9.     return wrapper 
  10.  
  11. @logging 
  12. def say(something): 
  13.     """say something""" 
  14.     print "say {}!".format(something) 
  15.  
  16. print say.__name__  # say 
  17. print say.__doc__ # say something  

看上去不錯!主要問題解決了,但其實還不太***。因為函數(shù)的簽名和源碼還是拿不到的。

  1. import inspect 
  2. print inspect.getargspec(say)  # failed 
  3. print inspect.getsource(say)  # failed  

如果要徹底解決這個問題可以借用第三方包,比如wrapt。后文有介紹。

不能裝飾@staticmethod 或者 @classmethod

當你想把裝飾器用在一個靜態(tài)方法或者類方法時,不好意思,報錯了。

  1. class Car(object): 
  2.     def __init__(self, model): 
  3.         self.model = model 
  4.  
  5.     @logging  # 裝飾實例方法,OK 
  6.     def run(self): 
  7.         print "{} is running!".format(self.model) 
  8.  
  9.     @logging  # 裝飾靜態(tài)方法,F(xiàn)ailed 
  10.     @staticmethod 
  11.     def check_model_for(obj): 
  12.         if isinstance(obj, Car): 
  13.             print "The model of your car is {}".format(obj.model) 
  14.         else
  15.             print "{} is not a car!".format(obj) 
  16.  
  17. ""
  18. Traceback (most recent call last): 
  19. ... 
  20.   File "example_4.py", line 10, in logging 
  21.     @wraps(func) 
  22.   File "C:\Python27\lib\functools.py", line 33, in update_wrapper 
  23.     setattr(wrapper, attr, getattr(wrapped, attr)) 
  24. AttributeError: 'staticmethod' object has no attribute '__module__' 
  25. "" 

前面已經(jīng)解釋了@staticmethod這個裝飾器,其實它返回的并不是一個callable對象,而是一個staticmethod對象,那么它是不符合裝飾器要求的(比如傳入一個callable對象),你自然不能在它之上再加別的裝飾器。要解決這個問題很簡單,只要把你的裝飾器放在@staticmethod之前就好了,因為你的裝飾器返回的還是一個正常的函數(shù),然后再加上一個@staticmethod是不會出問題的。

  1. class Car(object): 
  2.     def __init__(self, model): 
  3.         self.model = model 
  4.  
  5.     @staticmethod 
  6.     @logging  # 在@staticmethod之前裝飾,OK 
  7.     def check_model_for(obj): 
  8.         pass  

如何優(yōu)化你的裝飾器

嵌套的裝飾函數(shù)不太直觀,我們可以使用第三方包類改進這樣的情況,讓裝飾器函數(shù)可讀性更好。

decorator.py

decorator.py 是一個非常簡單的裝飾器加強包。你可以很直觀的先定義包裝函數(shù)wrapper(),再使用decorate(func, wrapper)方法就可以完成一個裝飾器。

  1. from decorator import decorate 
  2.  
  3. def wrapper(func, *args, **kwargs): 
  4.     """print log before a function.""" 
  5.     print "[DEBUG] {}: enter {}()".format(datetime.now(), func.__name__) 
  6.     return func(*args, **kwargs) 
  7.  
  8. def logging(func): 
  9.     return decorate(func, wrapper)  # 用wrapper裝飾func  

你也可以使用它自帶的@decorator裝飾器來完成你的裝飾器。

  1. from decorator import decorator 
  2.  
  3. @decorator 
  4. def logging(func, *args, **kwargs): 
  5.     print "[DEBUG] {}: enter {}()".format(datetime.now(), func.__name__) 
  6.     return func(*args, **kwargs)  

decorator.py實現(xiàn)的裝飾器能完整保留原函數(shù)的name,doc和args,唯一有問題的就是inspect.getsource(func)返回的還是裝飾器的源代碼,你需要改成inspect.getsource(func.__wrapped__)。

wrapt

wrapt是一個功能非常完善的包,用于實現(xiàn)各種你想到或者你沒想到的裝飾器。使用wrapt實現(xiàn)的裝飾器你不需要擔(dān)心之前inspect中遇到的所有問題,因為它都幫你處理了,甚至inspect.getsource(func)也準確無誤。

  1. import wrapt 
  2.  
  3. # without argument in decorator 
  4. @wrapt.decorator 
  5. def logging(wrapped, instance, args, kwargs):  # instance is must 
  6.     print "[DEBUG]: enter {}()".format(wrapped.__name__) 
  7.     return wrapped(*args, **kwargs) 
  8.  
  9. @logging 
  10. def say(something): pass  

使用wrapt你只需要定義一個裝飾器函數(shù),但是函數(shù)簽名是固定的,必須是(wrapped, instance, args, kwargs),注意第二個參數(shù)instance是必須的,就算你不用它。當裝飾器裝飾在不同位置時它將得到不同的值,比如裝飾在類實例方法時你可以拿到這個類實例。根據(jù)instance的值你能夠更加靈活的調(diào)整你的裝飾器。另外,args和kwargs也是固定的,注意前面沒有星號。在裝飾器內(nèi)部調(diào)用原函數(shù)時才帶星號。

如果你需要使用wrapt寫一個帶參數(shù)的裝飾器,可以這樣寫。

  1. def logging(level): 
  2.     @wrapt.decorator 
  3.     def wrapper(wrapped, instance, args, kwargs): 
  4.         print "[{}]: enter {}()".format(level, wrapped.__name__) 
  5.         return wrapped(*args, **kwargs) 
  6.     return wrapper 
  7.  
  8. @logging(level="INFO"
  9. def do(work): pass  

關(guān)于wrapt的使用,建議查閱官方文檔,在此不在贅述。

小結(jié)

Python的裝飾器和Java的注解(Annotation)并不是同一回事,和C#中的特性(Attribute)也不一樣,完全是兩個概念。

裝飾器的理念是對原函數(shù)、對象的加強,相當于重新封裝,所以一般裝飾器函數(shù)都被命名為wrapper(),意義在于包裝。函數(shù)只有在被調(diào)用時才會發(fā)揮其作用。比如@logging裝飾器可以在函數(shù)執(zhí)行時額外輸出日志,@cache裝飾過的函數(shù)可以緩存計算結(jié)果等等。

而注解和特性則是對目標函數(shù)或?qū)ο筇砑右恍傩?,相當于將其分類。這些屬性可以通過反射拿到,在程序運行時對不同的特性函數(shù)或?qū)ο蠹右愿深A(yù)。比如帶有Setup的函數(shù)就當成準備步驟執(zhí)行,或者找到所有帶有TestMethod的函數(shù)依次執(zhí)行等等。

至此我所了解的裝飾器已經(jīng)講完,但是還有一些內(nèi)容沒有提到,比如裝飾類的裝飾器。有機會再補充。謝謝觀看。

責(zé)任編輯:龐桂玉 來源: segmentfault
相關(guān)推薦

2010-02-01 17:50:32

Python裝飾器

2023-02-07 07:47:52

Python裝飾器函數(shù)

2024-05-24 11:36:28

Python裝飾器

2021-04-11 08:21:20

Python@property裝飾器

2025-01-22 15:58:46

2022-09-19 23:04:08

Python裝飾器語言

2024-09-12 15:32:35

裝飾器Python

2021-07-27 15:58:12

Python日志代碼

2022-09-27 11:01:08

Python裝飾器

2021-06-01 07:19:58

Python函數(shù)裝飾器

2023-12-11 15:51:00

Python裝飾器代碼

2025-07-01 09:46:30

2023-12-13 13:28:16

裝飾器模式Python設(shè)計模式

2022-09-21 09:04:07

Python裝飾器

2021-02-01 14:17:53

裝飾器外層函數(shù)里層函數(shù)

2022-09-26 09:02:54

TS 裝飾器TypeScript

2019-11-25 14:05:47

Python裝飾器數(shù)據(jù)

2024-11-09 08:26:52

Python裝飾器

2022-10-21 07:50:35

裝飾器Python編程

2020-05-10 16:59:56

Python裝飾器開發(fā)
點贊
收藏

51CTO技術(shù)棧公眾號

成人黄色图片网站| 黄色av网站在线| 亚洲久色影视| 国产亚洲精品久久久| 三上悠亚av一区二区三区| а√中文在线8| 久久―日本道色综合久久| 国产精品一区二区久久精品| 亚洲精品在线免费看| 国产精品高潮呻吟av| 亚洲一级二级| 欧美日韩免费不卡视频一区二区三区| 亚洲精品偷拍视频| 日本私人网站在线观看| 久久99最新地址| 68精品久久久久久欧美| 最新日韩免费视频| 久久丝袜视频| 欧美一二三四区在线| 日韩 欧美 高清| 日韩免费影院| 国产精品亲子乱子伦xxxx裸| 2019中文字幕全在线观看| 女人裸体性做爰全过| 亚洲成人短视频| 亚洲午夜在线电影| 国产精品美女在线播放| 天堂a√中文在线| 国产成人av电影在线| 国产精品视频xxxx| youjizz在线视频| 欧美色综合网| 久久久91精品国产一区不卡| av网站免费在线看| 日日狠狠久久偷偷综合色| 日韩一区二区三区视频| 亚洲一区精品视频在线观看| 日韩三区免费| 色哟哟精品一区| 黄色免费视频大全| a级片免费在线观看| 亚洲欧美韩国综合色| 91免费看蜜桃| 一级α片免费看刺激高潮视频| 国产欧美一区二区色老头| 欧美激情第三页| 卡通动漫亚洲综合| 婷婷亚洲五月| 久久精视频免费在线久久完整在线看| 91麻豆精品国产91久久综合| 免费精品国产的网站免费观看| 337p日本欧洲亚洲大胆精品| 麻豆网站免费观看| 亚洲成人1区| 一区二区三区色| 只有这里有精品| av在线麻豆| 伊人婷婷欧美激情| 成年人视频大全| 性欧美高清come| 一区二区日韩av| 青青在线免费视频| 色a资源在线| 亚洲最新在线观看| 亚洲精品无码国产| 第一中文字幕在线| 亚洲18色成人| 亚洲精品一区二区毛豆| 国产一二三在线观看| 欧美激情一区二区三区| 亚洲乱码一区二区三区三上悠亚| av在线免费观看网| 亚洲欧洲精品一区二区三区| 国产美女99p| 亚洲国产精品欧美久久| 成人免费观看av| 国产精品日日摸夜夜添夜夜av| 亚洲大尺度在线观看| 男人的天堂亚洲一区| 国产在线高清精品| 国产成人精品白浆久久69| 午夜在线观看免费一区| 日韩美女毛茸茸| 在线播放亚洲精品| 国产精品自拍毛片| 精品国产乱码久久久久久108| 色网站在线免费观看| 国产日韩三级在线| 桥本有菜av在线| 欧美v亚洲v| 一本大道久久a久久综合婷婷| 熟妇人妻无乱码中文字幕真矢织江| 欧美成人精品一区二区男人看| 成人av网在线| 视频一区二区三区免费观看| 国产成人l区| 黑人精品xxx一区| 欧美成人福利在线观看| 中文字幕一区二区三区四区久久| 国产视频欧美视频| 国产真实乱在线更新| 亚洲高清成人| 国产精品欧美亚洲777777| 亚洲成人777777| 欧美国产精品一区| 久久久久久高清| 开心激情综合网| 国产欧美一区在线| 欧美一区二区视频在线播放| 日韩av大片站长工具| 日韩丝袜情趣美女图片| 国产黄色大片免费看| 1024精品一区二区三区| 成人黄色免费在线观看| 日本在线视频1区| 亚洲精品国产无天堂网2021| 在线免费观看视频黄| 噜噜噜狠狠夜夜躁精品仙踪林| 久久精品视频免费播放| 亚洲 日本 欧美 中文幕| 国产成人av自拍| 亚洲一区二三| 日日av拍夜夜添久久免费| 亚洲成人a**站| 欧美性猛交xxxxx少妇| 日本不卡在线视频| 免费av一区二区三区| 亚洲资源一区| 欧美日韩国产高清一区二区| 日韩在线免费观看av| 一区二区三区成人精品| 91在线免费看片| 欧美r级在线| 欧美午夜一区二区三区免费大片| 给我免费观看片在线电影的| 欧美日本二区| 国产精品夜间视频香蕉| 国产视频第一区| 色综合网站在线| 国产 中文 字幕 日韩 在线| 激情婷婷久久| 国产chinese精品一区二区| 91网在线看| 91精品国产综合久久精品性色| 欧美午夜激情影院| 日韩av网站在线观看| 欧美日韩亚洲免费| 天堂av在线网| 亚洲免费一级电影| 欧美一区二区三区网站| 97久久超碰国产精品| 鲁一鲁一鲁一鲁一澡| 日韩极品在线| 欧洲精品在线视频| 欧美男男激情freegay| 欧美性生交大片免网| 9.1成人看片| 亚洲深夜福利| 色一情一乱一伦一区二区三欧美 | 性感美女久久精品| 一区二区免费在线观看视频| 国产视频久久| 日韩av电影免费在线| 精品网站在线| 粗暴蹂躏中文一区二区三区| www.国产欧美| 香蕉成人伊视频在线观看| 亚洲精品乱码久久| 国产精品久久久久久久免费软件| 欧美精品七区| 国产精品一区二区免费福利视频| 久久久精品国产一区二区| 国产三级第一页| 亚洲午夜精品久久久久久久久| 97精品人人妻人人| 九色成人国产蝌蚪91| 国产精品av在线播放| 亚洲高清在线观看视频| 亚洲一区二区成人在线观看| 免费在线观看成年人视频| 日韩精品免费专区| 成人在线观看www| 国产福利一区二区精品秒拍| 日韩天堂在线视频| 久久夜色精品国产噜噜亚洲av| 国产午夜精品一区二区三区视频 | 国产mv日韩mv欧美| 精品视频免费在线播放| 成人羞羞视频播放网站| 亚洲一区二区免费在线| 玖玖在线播放| 久久精品国亚洲| 五月天婷婷在线观看| 亚洲精品久久嫩草网站秘色| 精品一区二区视频在线观看| 日韩精品免费专区| www.亚洲成人网| 国产一区二区三区四区五区| 91系列在线播放| 亚洲最大成人| 欧美精品在线观看| 免费理论片在线观看播放老| 欧美一区二区三区在线视频| 草莓视频18免费观看| 伊人婷婷欧美激情| 99精品全国免费观看| 成人午夜在线播放| 国产福利在线免费| 亚欧成人精品| 隔壁人妻偷人bd中字| 日韩欧美中字| 麻豆av福利av久久av| 香蕉大人久久国产成人av| 国产精品久久久久久婷婷天堂| 国产美女一区视频| 久久精品国产免费观看| 麻豆app在线观看| 亚洲福利视频久久| 国产精品一品二区三区的使用体验| 日韩欧美中文字幕在线播放| 久草福利资源在线观看| 国产精品不卡在线观看| 少妇精品一区二区| 懂色av一区二区三区免费观看| 99re精彩视频| 蜜臀精品一区二区三区在线观看| 日本精品免费在线观看| 禁久久精品乱码| 影音先锋成人资源网站| 99精品小视频| 亚洲欧美日韩在线综合| 欧美精品一二| 日本精品一区二区三区高清 久久| 国产精品自在| 国产精品免费视频一区二区| 日韩中文字幕无砖| 91在线观看免费高清| 日韩一级视频| 国产日韩欧美影视| 久久av影院| 国产精品一区二区三区久久久| 免费亚洲电影| 国产第一区电影| 高清电影一区| 国产精品中文在线| 欧美aaaaaa| 国产日韩在线一区| 久久亚洲精品人成综合网| 国产精品69久久| 精品免费av在线| 国产美女精彩久久| 亚洲精品毛片| 亚洲aⅴ男人的天堂在线观看| 91视频亚洲| 91中文字精品一区二区| eeuss国产一区二区三区四区| 动漫3d精品一区二区三区 | 欧美电影网站| 国产精品成人aaaaa网站| 最新欧美电影| 国产日韩精品综合网站| 久久影院一区二区三区| 亚洲综合中文字幕在线| 6080亚洲理论片在线观看| 国产精品一区二区免费看| 欧美色图五月天| 神马影院一区二区三区| 亚洲不卡av不卡一区二区| 精品久久久无码人妻字幂| 亚洲午夜91| 每日在线更新av| 免费久久精品视频| 性鲍视频在线观看| av不卡免费在线观看| 久久精品—区二区三区舞蹈 | 一级日韩一区在线观看| 欧美一区免费| 啊啊啊一区二区| 久久精品久久久精品美女| 国产成人精品综合久久久久99| av激情亚洲男人天堂| 免费成人深夜天涯网站| 亚洲精选一二三| 啦啦啦免费高清视频在线观看| 欧美系列一区二区| 蜜桃久久一区二区三区| 在线观看欧美www| 香蕉成人app免费看片| 欧美又大又硬又粗bbbbb| av一级久久| 欧美视频小说| 你懂的国产精品| 成年人在线看片| 国产精品99久| 在线观看国产精品一区| 一区二区三区精品在线| 亚洲不卡视频在线观看| 日韩欧美国产wwwww| 毛片免费在线观看| 久久久久久久久久久久av| 欧美与亚洲与日本直播| 国产精品久久久久久久久久直播 | 毛片在线视频观看| 三级欧美在线一区| 人人妻人人做人人爽| 青娱乐精品在线视频| 中文字幕一区三区久久女搜查官| 国产精品久久久久久妇女6080 | 国产欧美精品| 午夜大片在线观看| 久久奇米777| 国产亚洲欧美久久久久| 91超碰这里只有精品国产| 欧美偷拍视频| 欧美激情奇米色| 免费一区二区三区四区| 日韩电影免费观看高清完整| 亚洲黄色成人| 日本xxxx免费| 中文字幕一区二区三区在线观看| 亚洲天堂视频网站| 亚洲成av人乱码色午夜| 黄色在线论坛| 国产精品欧美日韩一区二区| 一道本一区二区三区| 国产成人无码a区在线观看视频| 九色综合国产一区二区三区| 日本少妇高潮喷水xxxxxxx| 午夜精品免费在线| 丰满人妻一区二区| 欧美成人精品一区二区| 成人免费一区| 视频二区一区| 免费亚洲电影在线| 国产美女免费网站| 色婷婷精品大视频在线蜜桃视频| 日本毛片在线观看| 久久久久久久久网站| 伊人精品综合| 国产一区二区三区在线免费| 国产福利一区二区三区在线视频| 天天操夜夜操av| 制服丝袜成人动漫| a级影片在线| 97视频资源在线观看| 91精品在线观看国产| 天天av天天操| 亚洲精品老司机| 人妻少妇精品无码专区| 韩国国内大量揄拍精品视频| gay欧美网站| 欧美日韩国产综合在线| 美女尤物久久精品| 精品无码一区二区三区| 色偷偷一区二区三区| 福利视频在线看| 国产精品看片资源| 成人羞羞视频播放网站| 国模私拍视频在线观看| 亚洲日本va午夜在线影院| 亚洲黄色a级片| 午夜精品福利视频| 欧美日本成人| 亚洲精品www.| 亚洲国产综合在线| 四虎精品在线| 国产精品一区二区女厕厕| 亚洲91视频| 欧美xxxx×黑人性爽| 色婷婷av一区二区三区gif| 电影在线高清| 亚洲一区中文字幕在线观看| 国产精品分类| 国产jk精品白丝av在线观看 | 欧亚精品在线观看| 狠狠做深爱婷婷综合一区| 天堂av2020| 天天综合天天做天天综合| 第一页在线观看| 99r国产精品视频| 亚洲专区免费| 五月综合色婷婷| 亚洲大胆美女视频| av免费在线一区| www.男人天堂网| 久久精品日产第一区二区三区高清版 | 欧美日韩在线免费观看| h视频在线免费| 国产三区精品| 美女在线观看视频一区二区| 国产一级aa大片毛片| 伊人av综合网| 国产乱论精品| 在线黄色免费看| 狠狠综合久久av一区二区小说 | 国产chinesehd精品露脸| 色婷婷激情久久| 激情在线视频播放| 日韩免费三级| 不卡av免费在线观看|