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

被鄙視了,把Python當“弱”類型語言

開發 后端
Python 想必大家都已經很熟悉了,甚至關于它有用或者無用的論點大家可能也已經看膩了。但是無論如何,它作為一個將加入高考科目的語言還是有它獨到之處的,今天我們就再展開聊聊 Python。

[[433520]]

 Python 想必大家都已經很熟悉了,甚至關于它有用或者無用的論點大家可能也已經看膩了。但是無論如何,它作為一個將加入高考科目的語言還是有它獨到之處的,今天我們就再展開聊聊 Python。

Python 是一門動態強類型語言

《流暢的 Python》一書中提到,如果一門語言很少隱式轉換類型,說明它是強類型語言,例如 Java、C++ 和 Python 就是強類型語言。

△  Python 的強類型體現

同時如果一門語言經常隱式轉換類型,說明它是弱類型語言,PHP、JavaScript 和 Perl 是弱類型語言。

△  動態弱類型語言:JavaScript

當然上面這種簡單的示例對比,并不能確切的說 Python 是一門強類型語言,因為 Java 同樣支持 integer 和 string 相加操作,且 Java 是強類型語言。因此《流暢的 Python》一書中還有關于靜態類型和動態類型的定義:在編譯時檢查類型的語言是靜態類型語言,在運行時檢查類型的語言是動態類型語言。靜態語言需要聲明類型(有些現代語言使用類型推導避免部分類型聲明)。

綜上所述,關于 Python 是動態強類型語言是比較顯而易見沒什么爭議的。

Type Hints 初探

Python 在 PEP 484(Python Enhancement Proposals,Python 增強建議書)[https://www.python.org/dev/peps/pep-0484/]中提出了 Type Hints(類型注解)。進一步強化了 Python 是一門強類型語言的特性,它在 Python3.5 中第一次被引入。使用 Type Hints 可以讓我們編寫出帶有類型的 Python 代碼,看起來更加符合強類型語言風格。

這里定義了兩個 greeting 函數:

  •  普通的寫法如下: 
  1. name = "world"  
  2. def greeting(name):  
  3.     return "Hello " + name  
  4. greeting(name)  
  5.     加入了 Type Hints 的寫法如下:  
  6. name: str = "world"  
  7. def greeting(name: str) -> str:  
  8.     return "Hello " + name  
  9. greeting(name) 
  •  加入了 Type Hints 的寫法如下: 
  1. name: str = "world"  
  2. def greeting(name: str) -> str:  
  3.     return "Hello " + name  
  4. greeting(name) 

 以 PyCharm 為例,在編寫代碼的過程中 IDE 會根據函數的類型標注,對傳遞給函數的參數進行類型檢查。如果發現實參類型與函數的形參類型標注不符就會有如下提示:

常見數據結構的 Type Hints 寫法

上面通過一個 greeting 函數展示了 Type Hints 的用法,接下來我們就 Python 常見數據結構的 Type Hints 寫法進行更加深入的學習。

默認參數

Python 函數支持默認參數,以下是默認參數的 Type Hints 寫法,只需要將類型寫到變量和默認參數之間即可。 

  1. def greeting(name: str = "world") -> str:  
  2.     return "Hello " + name  
  3. greeting() 

自定義類型

對于自定義類型,Type Hints 同樣能夠很好的支持。它的寫法跟 Python 內置類型并無區別。 

  1. class Student(object):  
  2.     def __init__(self, name, age):  
  3.         self.name = name  
  4.         self.age = age  
  5. def student_to_string(s: Student) -> str:  
  6.     return f"student name: {s.name}, age: {s.age}."  
  7. student_to_string(Student("Tim", 18)) 

當類型標注為自定義類型時,IDE 也能夠對類型進行檢查。

容器類型

當我們要給內置容器類型添加類型標注時,由于類型注解運算符 [] 在 Python 中代表切片操作,因此會引發語法錯誤。所以不能直接使用內置容器類型當作注解,需要從 typing 模塊中導入對應的容器類型注解(通常為內置類型的首字母大寫形式)。 

  1. from typing import List, Tuple, Dict  
  2. l: List[int] = [1, 2, 3]  
  3. t: Tuple[str, ...] = ("a", "b")  
  4. d: Dict[str, int] = {  
  5.     "a": 1,  
  6.     "b": 2,  

不過 PEP 585[https://www.python.org/dev/peps/pep-0585/]的出現解決了這個問題,我們可以直接使用 Python 的內置類型,而不會出現語法錯誤。 

  1. l: list[int] = [1, 2, 3]  
  2. t: tuple[str, ...] = ("a", "b")  
  3. d: dict[str, int] = {  
  4.     "a": 1,  
  5.     "b": 2,  

類型別名

有些復雜的嵌套類型寫起來很長,如果出現重復,就會很痛苦,代碼也會不夠整潔。 

  1. config: list[tuple[str, int], dict[str, str]] = [  
  2.     ("127.0.0.1", 8080),  
  3.     {  
  4.         "MYSQL_DB": "db",  
  5.         "MYSQL_USER": "user",  
  6.         "MYSQL_PASS": "pass",  
  7.         "MYSQL_HOST": "127.0.0.1",  
  8.         "MYSQL_PORT": "3306",  
  9.     },  
  10.  
  11. def start_server(config: list[tuple[str, int], dict[str, str]]) -> None:  
  12.     ...  
  13. start_server(config) 

 此時可以通過給類型起別名的方式來解決,類似變量命名。 

  1. Config = list[tuple[str, int], dict[str, str]]  
  2. config: Config = [  
  3.     ("127.0.0.1", 8080),  
  4.     {  
  5.         "MYSQL_DB": "db",  
  6.         "MYSQL_USER": "user",  
  7.         "MYSQL_PASS": "pass",  
  8.         "MYSQL_HOST": "127.0.0.1",  
  9.         "MYSQL_PORT": "3306",  
  10.     },  
  11.  
  12. def start_server(config: Config) -> None:  
  13.     ...   
  14. start_server(config) 

這樣代碼看起來就舒服多了。

可變參數

Python 函數一個非常靈活的地方就是支持可變參數,Type Hints 同樣支持可變參數的類型標注。 

  1. def foo(*args: str, **kwargs: int) -> None:  
  2.     ...  
  3. foo("a", "b", 1, x=2y="c"

IDE 仍能夠檢查出來。

泛型

使用動態語言少不了泛型的支持,Type Hints 針對泛型也提供了多種解決方案。

TypeVar

使用 TypeVar 可以接收任意類型。 

  1. from typing import TypeVar  
  2. T = TypeVar("T")  
  3. def foo(*args: T, **kwargs: T) -> None:  
  4.     ...  
  5. foo("a", "b", 1, x=2y="c"

Union

如果不想使用泛型,只想使用幾種指定的類型,那么可以使用 Union 來做。比如定義 concat 函數只想接收 str 或 bytes 類型。 

  1. from typing import Union  
  2. T = Union[str, bytes]  
  3. def concat(s1: T, s2: T) -> T:  
  4.     return s1 + s2  
  5. concat("hello", "world")  
  6. concat(b"hello", b"world")  
  7. concat("hello", b"world")  
  8. concat(b"hello", "world") 

IDE 的檢查提示如下圖:

TypeVar 和 Union 區別

TypeVar 不只可以接收泛型,它也可以像 Union 一樣使用,只需要在實例化時將想要指定的類型范圍當作參數依次傳進來來即可。跟 Union 不同的是,使用 TypeVar 聲明的函數,多參數類型必須相同,而 Union 不做限制。 

  1. from typing import TypeVar  
  2. T = TypeVar("T", str, bytes)  
  3. def concat(s1: T, s2: T) -> T:  
  4.     return s1 + s2  
  5. concat("hello", "world")  
  6. concat(b"hello", b"world")  
  7. concat("hello", b"world") 

以下是使用 TypeVar 做限定類型時的 IDE 提示:

Optional

Type Hints 提供了 Optional 來作為 Union[X, None] 的簡寫形式,表示被標注的參數要么為 X 類型,要么為 None,Optional[X] 等價于 Union[X, None]。 

  1. from typing import Optional, Union  
  2. None => type(None)  
  3. def foo(arg: Union[int, None] = None) -> None:  
  4.     ...  
  5. def foo(arg: Optional[int] = None) -> None:  
  6.     ... 

Any

Any 是一種特殊的類型,可以代表所有類型。未指定返回值與參數類型的函數,都隱式地默認使用 Any,所以以下兩個 greeting 函數寫法等價: 

  1. from typing import Any  
  2. def greeting(name):  
  3.     return "Hello " + name  
  4. def greeting(name: Any) -> Any:  
  5.     return "Hello " + name 

當我們既想使用 Type Hints 來實現靜態類型的寫法,也不想失去動態語言特有的靈活性時,即可使用 Any。

Any 類型值賦給更精確的類型時,不執行類型檢查,如下代碼 IDE 并不會有錯誤提示: 

  1. from typing import Any  
  2. a: Any = None  
  3. a = []  # 動態語言特性  
  4. a = 2  
  5. s: str = ''  
  6. s = a  # Any 類型值賦給更精確的類型

可調用對象(函數、類等)

Python 中的任何可調用類型都可以使用 Callable 進行標注。如下代碼標注中 Callable[[int], str],[int] 表示可調用類型的參數列表,str 表示返回值。 

  1. from typing import Callable  
  2. def int_to_str(i: int) -> str:  
  3.     return str(i)  
  4. def f(fn: Callable[[int], str], i: int) -> str:  
  5.     return fn(i)  
  6. f(int_to_str, 2) 

自引用

當我們需要定義樹型結構時,往往需要自引用。當執行到 __init__ 方法時 Tree 類型還沒有生成,所以不能像使用 str 這種內置類型一樣直接進行標注,需要采用字符串形式“Tree”來對未生成的對象進行引用。 

  1. class Tree(object):  
  2.     def __init__(self, left: "Tree" = None, right: "Tree" = None):  
  3.         self.left = left  
  4.         self.right = right  
  5. tree1 = Tree(Tree(), Tree()) 

IDE 同樣能夠對自引用類型進行檢查。

此形式不僅能夠用于自引用,前置引用同樣適用。

鴨子類型

Python 一個顯著的特點是其對鴨子類型的大量應用,Type Hints 提供了 Protocol 來對鴨子類型進行支持。定義類時只需要繼承 Protocol 就可以聲明一個接口類型,當遇到接口類型的注解時,只要接收到的對象實現了接口類型的所有方法,即可通過類型注解的檢查,IDE 便不會報錯。這里的 Stream 無需顯式繼承 Interface 類,只需要實現了 close 方法即可。 

  1. from typing import Protocol  
  2. class Interface(Protocol):  
  3.     def close(self) -> None:  
  4.         ...  
  5. # class Stream(Interface):  
  6. class Stream:  
  7.     def close(self) -> None:  
  8.         ...  
  9. def close_resource(r: Interface) -> None:  
  10.     r.close()  
  11. f = open("a.txt")  
  12. close_resource(f)  
  13. s: StreamStream = Stream()  
  14. close_resource(s) 

由于內置的 open 函數返回的文件對象和 Stream 對象都實現了 close 方法,所以能夠通過 Type Hints 的檢查,而字符串“s”并沒有實現 close 方法,所以 IDE 會提示類型錯誤。

Type Hints 的其他寫法

實際上 Type Hints 不只有一種寫法,Python 為了兼容不同人的喜好和老代碼的遷移還實現了另外兩種寫法。

使用注釋編寫

來看一個 tornado 框架的例子(tornado/web.py)。適用于在已有的項目上做修改,代碼已經寫好了,后期需要增加類型標注。

使用單獨文件編寫(.pyi)

可以在源代碼相同的目錄下新建一個與 .py 同名的 .pyi 文件,IDE 同樣能夠自動做類型檢查。這么做的優點是可以對原來的代碼不做任何改動,完全解耦。缺點是相當于要同時維護兩份代碼。

Type Hints 實踐

基本上,日常編碼中常用的 Type Hints 寫法都已經介紹給大家了,下面就讓我們一起來看看如何在實際編碼中中應用 Type Hints。

dataclass——數據類

dataclass 是一個裝飾器,它可以對類進行裝飾,用于給類添加魔法方法,例如 __init__() 和 __repr__() 等,它在 PEP 557[https://www.python.org/dev/peps/pep-0557/]中被定義。 

  1. from dataclasses import dataclass, field  
  2. @dataclass  
  3. class User(object):  
  4.     id: int  
  5.     name: str  
  6.     friends: list[int] = field(default_factory=list 
  7. data = {  
  8.     "id": 123,  
  9.     "name": "Tim",  
  10.  
  11. user = User(**data)  
  12. print(user.id, user.name, user.friends)  
  13. > 123 Tim [] 

以上使用 dataclass 編寫的代碼同如下代碼等價: 

  1. class User(object):  
  2.     def __init__(self, id: int, name: str, friends=None):  
  3.         self.id = id  
  4.         self.name = name  
  5.         self.friends = friends or []  
  6. data = {  
  7.     "id": 123,  
  8.     "name": "Tim",  
  9.  
  10. user = User(**data) 
  11. print(user.id, user.name, user.friends)  
  12. > 123 Tim [] 

注意:dataclass 并不會對字段類型進行檢查。

可以發現,使用 dataclass 來編寫類可以減少很多重復的樣板代碼,語法上也更加清晰。

Pydantic

Pydantic 是一個基于 Python Type Hints 的第三方庫,它提供了數據驗證、序列化和文檔的功能,是一個非常值得學習借鑒的庫。以下是一段使用 Pydantic 的示例代碼: 

  1. from datetime import datetime  
  2. from typing import Optional  
  3. from pydantic import BaseModel  
  4. class User(BaseModel):  
  5.     id: int  
  6.     name = 'John Doe' 
  7.     signup_ts: Optional[datetime] = None  
  8.     friends: list[int] = []  
  9. external_data = {  
  10.     'id': '123',  
  11.     'signup_ts': '2021-09-02 17:00',  
  12.     'friends': [1, 2, '3'],  
  13.  
  14. user = User(**external_data)  
  15. print(user.id) 
  16. > 123  
  17. print(repr(user.signup_ts))  
  18. > datetime.datetime(2021, 9, 2, 17, 0)  
  19. print(user.friends)  
  20. > [1, 2, 3]  
  21. print(user.dict())  
  22. """  
  23.  
  24.     'id': 123,  
  25.     'signup_ts': datetime.datetime(2021, 9, 2, 17, 0),  
  26.     'friends': [1, 2, 3],  
  27.     'name': 'John Doe',  
  28.  
  29. """ 

注意:Pydantic 會對字段類型進行強制檢查。

Pydantic 寫法上跟 dataclass 非常類似,但它做了更多的額外工作,還提供了如 .dict() 這樣非常方便的方法。

再來看一個 Pydantic 進行數據驗證的示例,當 User 類接收到的參數不符合預期時,會拋出 ValidationError 異常,異常對象提供了 .json() 方法方便查看異常原因。 

  1. from pydantic import ValidationError  
  2. try:  
  3.     User(signup_ts='broken'friends=[1, 2, 'not number'])  
  4. except ValidationError as e:  
  5.     print(e.json())  
  6. """  
  7.  
  8.   {  
  9.     "loc": [  
  10.       "id"  
  11.     ],  
  12.     "msg": "field required",  
  13.     "type": "value_error.missing"  
  14.   },  
  15.   {  
  16.     "loc": [  
  17.       "signup_ts"  
  18.     ],  
  19.     "msg": "invalid datetime format",  
  20.     "type": "value_error.datetime"  
  21.   },  
  22.   { 
  23.     "loc": [  
  24.       "friends",  
  25.       2  
  26.     ],  
  27.     "msg": "value is not a valid integer",  
  28.     "type": "type_error.integer"  
  29.   }  
  30.  
  31. """ 

所有報錯信息都保存在一個 list 中,每個字段的報錯又保存在嵌套的 dict 中,其中 loc 標識了異常字段和報錯位置,msg 為報錯提示信息,type 則為報錯類型,這樣整個報錯原因一目了然。

MySQLHandler

MySQLHandler[https://github.com/jianghushinian/python-scripts/blob/main/scripts/mysql_handler_type_hints.py]是我對 pymysql 庫的封裝,使其支持使用 with 語法調用 execute 方法,并且將查詢結果從 tuple 替換成 object,同樣也是對 Type Hints 的應用。 

  1. class MySQLHandler(object):  
  2.     """MySQL handler"""  
  3.     def __init__(self):  
  4.         self.conn = pymysql.connect(  
  5.             host=DB_HOST 
  6.             port=DB_PORT 
  7.             user=DB_USER 
  8.             password=DB_PASS 
  9.             database=DB_NAME 
  10.             charset=DB_CHARSET 
  11.             client_flag=CLIENT.MULTI_STATEMENTS,  # execute multi sql statements  
  12.         )  
  13.         selfself.cursor = self.conn.cursor()  
  14.     def __del__(self):  
  15.         self.cursor.close()  
  16.         self.conn.close()  
  17.     @contextmanager 
  18.     def execute(self):  
  19.         try:  
  20.             yield self.cursor.execute  
  21.             self.conn.commit()  
  22.         except Exception as e:  
  23.             self.conn.rollback()  
  24.             logging.exception(e) 
  25.     @contextmanager  
  26.     def executemany(self):  
  27.         try:  
  28.             yield self.cursor.executemany  
  29.             self.conn.commit()  
  30.         except Exception as e:  
  31.             self.conn.rollback()  
  32.             logging.exception(e)  
  33.     def _tuple_to_object(self, data: List[tuple]) -> List[FetchObject]:  
  34.         obj_list = []  
  35.         attrs = [desc[0] for desc in self.cursor.description]  
  36.         for i in data:  
  37.             obj = FetchObject()  
  38.             for attr, value in zip(attrs, i):  
  39.                 setattr(obj, attr, value)  
  40.             obj_list.append(obj)  
  41.         return obj_list  
  42.     def fetchone(self) -> Optional[FetchObject]:  
  43.         result = self.cursor.fetchone() 
  44.         return self._tuple_to_object([result])[0] if result else None  
  45.     def fetchmany(self, size: Optional[int] = None) -> Optional[List[FetchObject]]:  
  46.         result = self.cursor.fetchmany(size)  
  47.         return self._tuple_to_object(result) if result else None  
  48.     def fetchall(self) -> Optional[List[FetchObject]]:  
  49.         result = self.cursor.fetchall()  
  50.         return self._tuple_to_object(result) if result else None

運行期類型檢查

Type Hints 之所以叫 Hints 而不是 Check,就是因為它只是一個類型的提示而非真正的檢查。上面演示的 Type Hints 用法,實際上都是 IDE 在幫我們完成類型檢查的功能,但實際上,IDE 的類型檢查并不能決定代碼執行期間是否報錯,僅能在靜態期做到語法檢查提示的功能。

要想實現在代碼執行階段強制對類型進行檢查,則需要我們通過自己編寫代碼或引入第三方庫的形式(如上面介紹的 Pydantic)。下面我通過一個 type_check 函數實現了運行期動態檢查類型,來供你參考: 

  1. from inspect import getfullargspec  
  2. from functools import wraps  
  3. from typing import get_type_hints  
  4. def type_check(fn):  
  5.     @wraps(fn)  
  6.     def wrapper(*args, **kwargs):  
  7.         fn_args = getfullargspec(fn)[0]  
  8.         kwargs.update(dict(zip(fn_args, args)))  
  9.         hints = get_type_hints(fn)  
  10.         hints.pop("return", None)  
  11.         for name, type_ in hints.items():  
  12.             if not isinstance(kwargs[name], type_):  
  13.                 raise TypeError(f"expected {type_.__name__}, got {type(kwargs[name]).__name__} instead")  
  14.         return fn(**kwargs)  
  15.     return wrapper  
  16. # name: str = "world"  
  17. name: int = 2  
  18. @type_check  
  19. def greeting(name: str) -> str:  
  20.     return str(name)  
  21. print(greeting(name))  
  22. > TypeError: expected str, got int instead 

只要給 greeting 函數打上 type_check 裝飾器,即可實現運行期類型檢查。 

 

責任編輯:龐桂玉 來源: Python之禪
相關推薦

2020-08-31 19:17:24

Python強類型語言弱類型語言

2021-03-11 16:45:29

TCP程序C語言

2023-08-28 12:07:06

UUIDMySQL

2018-11-01 15:20:17

前端程序員編程語言

2011-11-25 09:27:30

Dart

2019-02-19 15:01:40

Python

2021-03-01 14:51:20

程序員代碼博主

2020-10-13 16:30:31

語言鏈表數組

2020-11-12 07:49:18

MySQL

2016-08-08 15:03:54

騰訊云電商騰訊云天御系統

2016-06-28 11:28:11

2021-10-11 13:25:42

語言Go類型

2020-12-14 13:39:39

AI人工智能算法

2020-12-14 15:26:38

AIAI算法

2021-11-25 07:42:11

命令Linux系統

2013-06-20 11:11:00

程序員經理

2019-11-15 08:48:55

區塊鏈安全應用程序

2024-06-18 08:31:33

2010-02-02 16:22:37

Python動態類型語

2023-11-13 08:03:53

Next.js命令變量
點贊
收藏

51CTO技術棧公眾號

成av人片在线观看www| 四虎影院在线免费播放| 日韩精品一区二区三区免费视频| 亚洲精品乱码久久久久久| 亚洲free嫩bbb| 丰满少妇乱子伦精品看片| 精品日韩免费| 日韩欧美亚洲一区二区| 国产在线青青草| 好吊日视频在线观看| 成人动漫一区二区三区| 久久精品一区中文字幕| 蜜臀视频在线观看| 激情久久一区二区| 亚洲成a人v欧美综合天堂| 水蜜桃亚洲一二三四在线| 精品人妻一区二区三区蜜桃| 首页欧美精品中文字幕| 欧美国产第一页| 妺妺窝人体色WWW精品| 一区二区三区欧洲区| 色屁屁一区二区| 成人免费观看在线| 午夜伦理在线| 久久久精品影视| 国产精品免费一区二区| 一起草av在线| 99精品在线视频观看| 欧美理论视频| 亚洲精品美女在线观看| 红桃视频一区二区三区免费| 日本在线视频一区二区| 欧美日韩国产中文精品字幕自在自线| 香蕉精品视频在线| 国产视频在线看| 99久久精品国产精品久久| 亚洲综合中文字幕68页| 中文字幕第99页| 校园激情久久| 午夜美女久久久久爽久久| 国产精品久久久精品四季影院| 成人羞羞动漫| 国产一区二区黑人欧美xxxx| 30一40一50老女人毛片| 高清日韩欧美| 欧美草草影院在线视频| 奇米777在线| 国产精品一级在线观看| 欧美理论电影在线| 777视频在线| 电影一区电影二区| 在线亚洲欧美专区二区| 欧美少妇性生活视频| 在线观看爽视频| 岛国av一区二区三区| 日韩小视频在线播放| 96av在线| 欧美午夜宅男影院在线观看| 一区二区传媒有限公司| 欧美三级网站| 日韩欧美中文第一页| 日本一本二本在线观看| 日本电影欧美片| 欧美伊人精品成人久久综合97 | 91精品国产自产在线观看永久| 国产免费一级视频| 欧美a一区二区| 国产美女91呻吟求| 国产免费不卡视频| 国产欧美日韩综合精品一区二区三区| 亚洲永久网站| 国产精品成人一区二区| 中文字幕码精品视频网站| 久久国产精品无码网站| 成人精品久久一区二区三区| 国产喷水吹潮视频www| 国产高清成人在线| 精品国产乱码久久久久久蜜柚| 亚洲AV成人无码一二三区在线| 91蝌蚪porny成人天涯| 日韩和欧美的一区二区| 精品孕妇一区二区三区| 亚洲成人激情自拍| 成年人黄色片视频| 亚洲资源在线| 亚洲国产精品免费| xxxxx99| 欧美a级一区| 88国产精品欧美一区二区三区| 国产伦精品一区二区三区视频网站| 日本三级亚洲精品| 999国产视频| 免费毛片在线| 亚洲男女一区二区三区| 国产a级一级片| 91视频成人| 国产丝袜一区二区三区| 国产探花视频在线| 亚洲国内欧美| 成人h视频在线| 天天干天天摸天天操| 国产精品人成在线观看免费| 大陆极品少妇内射aaaaaa| 美女在线视频免费| 欧美精品在线观看播放| 中文字幕乱码在线| 天天久久综合| 热门国产精品亚洲第一区在线| 国产欧美一级片| 久久九九国产精品| 丁香婷婷综合激情| 亚洲18在线| 亚洲精品视频播放| 欧美偷拍第一页| 日本加勒比一区| 粉嫩嫩av羞羞动漫久久久 | 日本韩国免费观看| 中文字幕五月欧美| 妞干网在线免费视频| 亚洲精品一区国产| 最近更新的2019中文字幕| 精品成人免费视频| 国产成人免费在线观看| 特级西西444www大精品视频| 无码小电影在线观看网站免费| 欧美一区二区私人影院日本| 国产精品一二三区在线观看| 国产欧美精品| 国产日韩欧美一区二区三区四区| 羞羞视频在线免费国产| 欧美日韩国产小视频| 熟女俱乐部一区二区视频在线| 亚洲小说欧美另类婷婷| 91成人免费视频| 大地资源网3页在线观看| 欧美日韩在线播放三区四区| 亚洲一级中文字幕| 亚洲精品日本| 国产亚洲福利社区| 在线观看的网站你懂的| 91精品国产美女浴室洗澡无遮挡| 久久久国产一级片| 青草国产精品久久久久久| 日本一区二区精品| 日韩一区精品| 正在播放亚洲1区| 中文字幕丰满人伦在线| 欧美极品少妇xxxxⅹ高跟鞋| 免费日韩中文字幕| 精品视频亚洲| 国产精品久久久久久久久粉嫩av | 91一区二区视频| 中文幕一区二区三区久久蜜桃| 亚洲高清在线免费观看| 欧美呦呦网站| 国产欧美日韩亚洲精品| 欧美天天影院| 欧美一区二区三区视频在线观看 | 欧美午夜无遮挡| 成人高清在线观看| 国产精品18p| 成人免费视频视频在线观看免费 | 草美女在线观看| 亚洲成人网在线| 日韩中文字幕在线观看视频| 国产亚洲一二三区| 99热这里只有精品在线播放| 99久久激情| 99视频在线| 国产在线看片免费视频在线观看| 国产视频一区在线| 亚洲手机在线观看| 亚洲激情五月婷婷| 国产成人精品无码片区在线| 裸体一区二区| 伊人久久大香线蕉午夜av| 韩国一区二区三区视频| 97国产精品视频人人做人人爱| 久久精品国产亚洲a∨麻豆| 精品污污网站免费看| 我家有个日本女人| 不卡欧美aaaaa| 日韩肉感妇bbwbbwbbw| 中文精品久久| 久久伊人一区| 伊人久久大香线蕉综合影院首页| 欧美激情亚洲视频| 国产视频第一页在线观看| 欧美一级片在线观看| 日韩精品一区二区av| 中文字幕不卡在线| 亚洲香蕉中文网| 青青草伊人久久| av在线com| 成人久久综合| 国产视频一区二区不卡| 先锋欧美三级| 欧美激情高清视频| 一级毛片视频在线| 亚洲精品国产精品国产自| 中文字幕一区二区三区四区视频| 一区二区三区不卡视频在线观看 | 国产精品久久久久久久久妇女| 国产传媒欧美日韩| 欧美综合影院| 青青草99啪国产免费| 亚洲男同gay网站| 国产精品久久久久毛片软件| 91精品在线影院| 不卡一本毛片| 久久亚洲精品成人| 国产精品一区在线看| 精品国产人成亚洲区| 一级黄色片在线播放| 欧美日韩加勒比精品一区| 久草综合在线视频| 欧美激情一区二区| 亚洲一区二区三区无码久久| 国产精品白丝jk白祙喷水网站| 亚洲成人av免费看| 亚洲女同同性videoxma| 久久久99精品视频| 亚洲精品国产首次亮相| 日韩成人av电影在线| 欧美理论电影在线精品| 91精品久久香蕉国产线看观看 | 51成人做爰www免费看网站| 神马久久资源| 欧洲s码亚洲m码精品一区| 欧美xxx黑人xxx水蜜桃| 不卡av在线网站| 永久免费av片在线观看全网站| 亚洲美女动态图120秒| 蜜臀久久久久久999| 日韩午夜在线影院| 91福利在线观看视频| 欧美视频完全免费看| www.久久视频| 在线观看国产一区二区| 日本一区二区三区精品| 精品久久中文字幕| 国产香蕉视频在线| 图片区小说区区亚洲影院| 国产真实的和子乱拍在线观看| 亚洲精品久久久蜜桃| 亚洲熟女www一区二区三区| 亚洲欧洲av在线| 性欧美疯狂猛交69hd| 国产精品乱子久久久久| 精品国产aaa| 中文子幕无线码一区tr| jizzjizzjizz国产| 国产精品国产三级国产aⅴ中文| 永久免费毛片在线观看| 国产色91在线| 欧美亚洲色综久久精品国产| 国产精品每日更新在线播放网址| 日本一级免费视频| 亚洲国产精品成人综合| 在线观看免费黄色网址| 亚洲欧美国产高清| 久久久精品一区二区涩爱| 亚洲国产成人高清精品| 久久这里只有精品8| 99久久这里有精品| 97超级碰碰| 欧美综合精品| 天天好比中文综合网| 久久久久国产精品| 分分操这里只有精品| 亚洲欧美日本日韩| 在线免费视频a| 激情五月婷婷综合| 91精品啪在线观看国产| 久久综合色鬼综合色| 日本一区二区视频在线播放| 最新成人av在线| 国产精品99精品| 在线观看国产一区二区| 国产美女免费看| 亚洲福利视频久久| 国产精品四虎| 欧美日韩成人免费| 国产高清不卡| 91免费视频国产| 欧美激情99| 亚洲高清乱码| 亚洲精品少妇| 九色porny自拍| 成人午夜av电影| 一级特黄曰皮片视频| 亚洲精品国产精品乱码不99| 国产精品人人人人| 91精品国产全国免费观看| 欧美孕妇孕交xxⅹ孕妇交| 日韩视频免费大全中文字幕| 成人影院在线播放| 国产精品亚洲片夜色在线| 成人爽a毛片| 亚洲一区影院| 亚洲九九精品| 天堂在线一区二区三区| 91视频xxxx| 激情五月婷婷在线| 欧美日韩一区国产| 天堂在线视频网站| 久久久精品网站| 日产精品一区| 国产综合色一区二区三区| 91日韩欧美| 欧美成人黑人猛交| 大尺度一区二区| 中文字幕观看av| 日本久久一区二区| 神马午夜在线观看| 久久网福利资源网站| 色猫猫成人app| 久久久久久99| 亚洲精品裸体| 国产综合内射日韩久| 综合欧美一区二区三区| 凹凸精品一区二区三区| 亚洲国产精品小视频| 99在线播放| 成人免费观看a| 色综合天天爱| 欧美伦理片在线看| 久久久久久久久久久久久夜| 日本少妇裸体做爰| 日韩欧美高清在线| 91亚洲天堂| 91久久中文字幕| 日韩欧美字幕| mm131国产精品| 中文字幕一区二区三区四区 | 日韩专区欧美专区| 日韩精品人妻中文字幕有码| 一区二区三区在线观看视频 | 亚洲乱码av中文一区二区| 久久亚洲导航| 97超级碰碰| 亚洲婷婷在线| 2一3sex性hd| 精品国产91久久久久久老师| 亚洲精品久久久狠狠狠爱| 久久亚洲精品中文字幕冲田杏梨| 一级欧美视频| 日本精品福利视频| 成人免费毛片片v| 精品无码人妻一区二区三区| 亚洲成人黄色在线| 91九色porn在线资源| 久久99九九| 天堂va蜜桃一区二区三区漫画版| 波多野结衣办公室33分钟| 欧美日韩中文字幕综合视频| 日韩av地址| 国产精品久久久久久久天堂| 欧美成人milf| 日本少妇一区二区三区| 一区二区欧美在线观看| 日本成人动漫在线观看| 欧美一区二区三区免费观看| 精品国产乱码久久久久久蜜坠欲下 | 欲香欲色天天天综合和网| 欧美另类高清视频在线| 日本aⅴ精品一区二区三区 | 久久精品国内一区二区三区水蜜桃| 欧美大片久久久| 亚洲综合视频网| 日本视频在线观看一区二区三区| 国产福利精品在线| 亚洲精品91| a级一a一级在线观看| 色香色香欲天天天影视综合网| eeuss影院www在线播放| 成人乱色短篇合集| 亚洲经典三级| 日本美女xxx| 日韩欧美色综合| 一区二区乱码| 国产四区在线观看| 97se亚洲国产综合在线| 天天干天天插天天射| 欧美日韩国产成人高清视频| 亚洲图区在线| 永久av免费在线观看| 大伊人狠狠躁夜夜躁av一区| 午夜激情在线观看| 国产精品视频免费一区| 日韩成人伦理电影在线观看| 国产精品老熟女一区二区| 亚洲欧美激情在线视频| 91麻豆精品国产91久久久更新资源速度超快| 日韩极品视频在线观看| 中文字幕不卡在线观看| 欧美 日韩 国产 成人 在线| 国产精品美女无圣光视频| 亚洲承认在线| 欧美性x x x|