国产乱子伦高清露脸对白-国产精品欧美久久久久天天影视-国产91视频一区-亚洲欧美日产综合在线网-黄视频网站在线看-国产欧美亚洲精品第1页-亚洲www在线-大学生女人三级在线播放-日本在线视频www鲁啊鲁-国产成人精品一区二区仙踪林-69精品欧美一区二区三区-成人欧美亚洲-日本污污网站-中国妞xxxhd露脸偷拍视频-国产精品aⅴ在线观看-精品中文字幕在线

極客小將

您現在的位置是:首頁 » python編程資訊

資訊內容

迅速掌握Python中的Hook鉤子函數

極客小將2020-12-22-
簡介Python教程欄目介紹Python中的Hook鉤子函數大量免費學習推薦,敬請訪問python教程(視頻)1.什么是Hook經常會聽到鉤子函數(hookfunction)這個概念,最近在看目標檢測開源框架mmdetection,里面也出現大量Hook的編程方式,那到底什么是hook?hook的作用是

極客小將版權所有。

<link rel="stylesheet" />python教程欄目介紹Python中的Hook鉤子函數

YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

大量免費學習推薦,敬請訪問python教程(視頻)YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

1. 什么是Hook
YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

經常會聽到鉤子函數(hook function)這個概念,**近在看目標檢測開源框架mmdetection,里面也出現大量Hook的編程方式,那到底什么是hook?hook的作用是什么?YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

what is hook ?鉤子hook,顧名思義,可以理解是一個掛鉤,作用是有需要的時候掛一個東西上去。具體的解釋是:鉤子函數是把我們自己實現的hook函數在某一時刻掛接到目標掛載點上。YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

hook函數的作用 舉個例子,hook的概念在windows桌面軟件開發很常見,特別是各種事件觸發的機制; 比如C++的MFC程序中,要監聽鼠標左鍵按下的時間,MFC提供了一個onLeftKeyDown的鉤子函數。很顯然,MFC框架并沒有為我們實現onLeftKeyDown具體的操作,只是為我們提供一個鉤子,當我們需要處理的時候,只要去重寫這個函數,把我們需要操作掛載在這個鉤子里,如果我們不掛載,MFC事件觸發機制中執行的就是空的操作。YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

從上面可知YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

hook函數是程序中預定義好的函數,這個函數處于原有程序流程當中(暴露一個鉤子出來)YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

我們需要再在有流程中鉤子定義的函數塊中實現某個具體的細節,需要把我們的實現,掛接或者注冊(register)到鉤子里,使得hook函數對目標可用YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

hook 是一種編程機制,和具體的語言沒有直接的關系YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

如果從設計模式上看,hook模式是模板方法的擴展YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

鉤子只有注冊的時候,才會使用,所以原有程序的流程中,沒有注冊或掛載時,執行的是空(即沒有執行任何操作)YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

本文用python來解釋hook的實現方式,并展示在開源項目中hook的應用案例。hook函數和我們常聽到另外一個名稱:回調函數(callback function)功能是類似的,可以按照同種模式來理解。YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

2. hook實現例子

據我所知,hook函數**常使用在某種流程處理當中。這個流程往往有很多步驟。hook函數常常掛載在這些步驟中,為增加額外的一些操作,提供靈活性。YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

下面舉一個簡單的例子,這個例子的目的是實現一個通用往隊列中插入內容的功能。流程步驟有2個YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

需要再插入隊列前,對數據進行篩選 input_filter_fnYqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

插入隊列 insert_queueYqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

class ContentStash(object): """ content stash for online operation pipeline is 1. input_filter: filter some contents, no use to user 2. insert_queue(redis or other broker): insert useful content to queue """ def __init__(self): self.input_filter_fn = None self.broker = [] def register_input_filter_hook(self, input_filter_fn): """ register input filter function, parameter is content dict Args: input_filter_fn: input filter function Returns: """ self.input_filter_fn = input_filter_fn def insert_queue(self, content): """ insert content to queue Args: content: dict Returns: """ self.broker.append(content) def input_pipeline(self, content, use=False): """ pipeline of input for content stash Args: use: is use, defaul False content: dict Returns: """ if not use: return # input filter if self.input_filter_fn: _filter = self.input_filter_fn(content) # insert to queue if not _filter: self.insert_queue(content) # test ## 實現一個你所需要的鉤子實現:比如如果content 包含time就過濾掉,否則插入隊列 def input_filter_hook(content): """ test input filter hook Args: content: dict Returns: None or content """ if content.get('time') is None: return else: return content # 原有程序 content = {'filename': 'test.jpg', 'b64_file': "#test", 'data': {"result": "cat", "probility": 0.9}} content_stash = ContentStash('audit', work_dir='') # 掛上鉤子函數, 可以有各種不同鉤子函數的實現,但是要主要函數輸入輸出必須保持原有程序中一致,比如這里是content content_stash.register_input_filter_hook(input_filter_hook) # 執行流程 content_stash.input_pipeline(content) 3. hook在開源框架中的應用3.1 keras

在深度學習訓練流程中,hook函數體現的淋漓盡致。YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

一個訓練過程(不包括數據準備),會輪詢多次訓練集,每次稱為一個epoch,每個epoch又分為多個batch來訓練。流程先后拆解成:YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

開始訓練YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

訓練一個epoch前YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

訓練一個batch前YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

訓練一個batch后YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

訓練一個epoch后YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

評估驗證集YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

結束訓練YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

這些步驟是穿插在訓練一個batch數據的過程中,這些可以理解成是鉤子函數,我們可能需要在這些鉤子函數中實現一些定制化的東西,比如在訓練一個epoch后我們要保存下訓練的模型,在結束訓練時用**好的模型執行下測試集的效果等等。YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

keras中是通過各種回調函數來實現鉤子hook功能的。這里放一個callback的父類,定制時只要繼承這個父類,實現你過關注的鉤子就可以了。YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

@keras_export('keras.callbacks.Callback') class Callback(object): """Abstract base class used to build new callbacks. Attributes: params: Dict. Training parameters (eg. verbosity, batch size, number of epochs...). model: Instance of `keras.models.Model`. Reference of the model being trained. The `logs` dictionary that callback methods take as argument will contain keys for quantities relevant to the current batch or epoch (see method-specific docstrings). """ def __init__(self): self.validation_data = None # pylint: disable=g-missing-from-attributes self.model = None # Whether this Callback should only run on the chief worker in a # Multi-Worker setting. # TODO(omalleyt): Make this attr public once solution is stable. self._chief_worker_only = None self._supports_tf_logs = False def set_params(self, params): self.params = params def set_model(self, model): self.model = model @doc_controls.for_subclass_implementers @generic_utils.default def on_batch_begin(self, batch, logs=None): """A backwards compatibility alias for `on_train_batch_begin`.""" @doc_controls.for_subclass_implementers @generic_utils.default def on_batch_end(self, batch, logs=None): """A backwards compatibility alias for `on_train_batch_end`.""" @doc_controls.for_subclass_implementers def on_epoch_begin(self, epoch, logs=None): """Called at the start of an epoch. Subclasses should override for any actions to run. This function should only be called during TRAIN mode. Arguments: epoch: Integer, index of epoch. logs: Dict. Currently no data is passed to this argument for this method but that may change in the future. """ @doc_controls.for_subclass_implementers def on_epoch_end(self, epoch, logs=None): """Called at the end of an epoch. Subclasses should override for any actions to run. This function should only be called during TRAIN mode. Arguments: epoch: Integer, index of epoch. logs: Dict, metric results for this training epoch, and for the validation epoch if validation is performed. Validation result keys are prefixed with `val_`. """ @doc_controls.for_subclass_implementers @generic_utils.default def on_train_batch_begin(self, batch, logs=None): """Called at the beginning of a training batch in `fit` methods. Subclasses should override for any actions to run. Arguments: batch: Integer, index of batch within the current epoch. logs: Dict, contains the return value of `model.train_step`. Typically, the values of the `Model`'s metrics are returned. Example: `{'loss': 0.2, 'accuracy': 0.7}`. """ # For backwards compatibility. self.on_batch_begin(batch, logs=logs) @doc_controls.for_subclass_implementers @generic_utils.default def on_train_batch_end(self, batch, logs=None): """Called at the end of a training batch in `fit` methods. Subclasses should override for any actions to run. Arguments: batch: Integer, index of batch within the current epoch. logs: Dict. Aggregated metric results up until this batch. """ # For backwards compatibility. self.on_batch_end(batch, logs=logs) @doc_controls.for_subclass_implementers @generic_utils.default def on_test_batch_begin(self, batch, logs=None): """Called at the beginning of a batch in `evaluate` methods. Also called at the beginning of a validation batch in the `fit` methods, if validation data is provided. Subclasses should override for any actions to run. Arguments: batch: Integer, index of batch within the current epoch. logs: Dict, contains the return value of `model.test_step`. Typically, the values of the `Model`'s metrics are returned. Example: `{'loss': 0.2, 'accuracy': 0.7}`. """ @doc_controls.for_subclass_implementers @generic_utils.default def on_test_batch_end(self, batch, logs=None): """Called at the end of a batch in `evaluate` methods. Also called at the end of a validation batch in the `fit` methods, if validation data is provided. Subclasses should override for any actions to run. Arguments: batch: Integer, index of batch within the current epoch. logs: Dict. Aggregated metric results up until this batch. """ @doc_controls.for_subclass_implementers @generic_utils.default def on_predict_batch_begin(self, batch, logs=None): """Called at the beginning of a batch in `predict` methods. Subclasses should override for any actions to run. Arguments: batch: Integer, index of batch within the current epoch. logs: Dict, contains the return value of `model.predict_step`, it typically returns a dict with a key 'outputs' containing the model's outputs. """ @doc_controls.for_subclass_implementers @generic_utils.default def on_predict_batch_end(self, batch, logs=None): """Called at the end of a batch in `predict` methods. Subclasses should override for any actions to run. Arguments: batch: Integer, index of batch within the current epoch. logs: Dict. Aggregated metric results up until this batch. """ @doc_controls.for_subclass_implementers def on_train_begin(self, logs=None): """Called at the beginning of training. Subclasses should override for any actions to run. Arguments: logs: Dict. Currently no data is passed to this argument for this method but that may change in the future. """ @doc_controls.for_subclass_implementers def on_train_end(self, logs=None): """Called at the end of training. Subclasses should override for any actions to run. Arguments: logs: Dict. Currently the output of the last call to `on_epoch_end()` is passed to this argument for this method but that may change in the future. """ @doc_controls.for_subclass_implementers def on_test_begin(self, logs=None): """Called at the beginning of evaluation or validation. Subclasses should override for any actions to run. Arguments: logs: Dict. Currently no data is passed to this argument for this method but that may change in the future. """ @doc_controls.for_subclass_implementers def on_test_end(self, logs=None): """Called at the end of evaluation or validation. Subclasses should override for any actions to run. Arguments: logs: Dict. Currently the output of the last call to `on_test_batch_end()` is passed to this argument for this method but that may change in the future. """ @doc_controls.for_subclass_implementers def on_predict_begin(self, logs=None): """Called at the beginning of prediction. Subclasses should override for any actions to run. Arguments: logs: Dict. Currently no data is passed to this argument for this method but that may change in the future. """ @doc_controls.for_subclass_implementers def on_predict_end(self, logs=None): """Called at the end of prediction. Subclasses should override for any actions to run. Arguments: logs: Dict. Currently no data is passed to this argument for this method but that may change in the future. """ def _implements_train_batch_hooks(self): """Determines if this Callback should be called for each train batch.""" return (not generic_utils.is_default(self.on_batch_begin) or not generic_utils.is_default(self.on_batch_end) or not generic_utils.is_default(self.on_train_batch_begin) or not generic_utils.is_default(self.on_train_batch_end))

這些鉤子的原始程序是在模型訓練流程中的YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

keras源碼位置: tensorflowpythonkerasengine raining.pyYqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

部分摘錄如下(## I am hook):YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

# Container that configures and calls `tf.keras.Callback`s. if not isinstance(callbacks, callbacks_module.CallbackList): callbacks = callbacks_module.CallbackList( callbacks, add_history=True, add_progbar=verbose != 0, model=self, verbose=verbose, epochs=epochs, steps=data_handler.inferred_steps) ## I am hook callbacks.on_train_begin() training_logs = None # Handle fault-tolerance for multi-worker. # TODO(omalleyt): Fix the ordering issues that mean this has to # happen after `callbacks.on_train_begin`. data_handler._initial_epoch = ( # pylint: disable=protected-access self._maybe_load_initial_epoch_from_ckpt(initial_epoch)) for epoch, iterator in data_handler.enumerate_epochs(): self.reset_metrics() callbacks.on_epoch_begin(epoch) with data_handler.catch_stop_iteration(): for step in data_handler.steps(): with trace.Trace( 'TraceContext', graph_type='train', epoch_num=epoch, step_num=step, batch_size=batch_size): ## I am hook callbacks.on_train_batch_begin(step) tmp_logs = train_function(iterator) if data_handler.should_sync: context.async_wait() logs = tmp_logs # No error, now safe to assign to logs. end_step = step + data_handler.step_increment callbacks.on_train_batch_end(end_step, logs) epoch_logs = copy.copy(logs) # Run validation. ## I am hook callbacks.on_epoch_end(epoch, epoch_logs)3.2 mmdetection

mmdetection是一個目標檢測的開源框架,集成了許多不同的目標檢測深度學習算法(pytorch版),如faster-rcnn, fpn, retianet等。里面也大量使用了hook,暴露給應用實現流程中具體部分。YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

詳見https://github.com/open-mmlab/mmdetectionYqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

這里看一個訓練的調用例子(摘錄)(https://github.com/open-mmlab/mmdetection/blob/5d592154cca589c5113e8aadc8798bbc73630d98/mmdet/apis/train.py)YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

def train_detector(model, dataset, cfg, distributed=False, validate=False, timestamp=None, meta=None): logger = get_root_logger(cfg.log_level) # prepare data loaders # put model on gpus # build runner optimizer = build_optimizer(model, cfg.optimizer) runner = EpochBasedRunner( model, optimizer=optimizer, work_dir=cfg.work_dir, logger=logger, meta=meta) # an ugly workaround to make .log and .log.json filenames the same runner.timestamp = timestamp # fp16 setting # register hooks runner.register_training_hooks(cfg.lr_config, optimizer_config, cfg.checkpoint_config, cfg.log_config, cfg.get('momentum_config', None)) if distributed: runner.register_hook(DistSamplerSeedHook()) # register eval hooks if validate: # Support batch_size > 1 in validation eval_cfg = cfg.get('evaluation', {}) eval_hook = DistEvalHook if distributed else EvalHook runner.register_hook(eval_hook(val_dataloader, **eval_cfg)) # user-defined hooks if cfg.get('custom_hooks', None): custom_hooks = cfg.custom_hooks assert isinstance(custom_hooks, list), f'custom_hooks expect list type, but got {type(custom_hooks)}' for hook_cfg in cfg.custom_hooks: assert isinstance(hook_cfg, dict), 'Each item in custom_hooks expects dict type, but got ' f'{type(hook_cfg)}' hook_cfg = hook_cfg.copy() priority = hook_cfg.pop('priority', 'NORMAL') hook = build_from_cfg(hook_cfg, HOOKS) runner.register_hook(hook, priority=priority)4. 總結

本文介紹了hook的概念和應用,并給出了python的實現細則。希望對比有幫助。總結如下:YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

hook函數是流程中預定義好的一個步驟,沒有實現YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

掛載或者注冊時, 流程執行就會執行這個鉤子函數YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

回調函數和hook函數功能上是一致的YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

hook設計方式帶來靈活性,如果流程中有一個步驟,你想讓調用方來實現,你可以用hook函數YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

相關免費學習推薦:php編程(視頻)
YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

以上就是迅速掌握Python中的Hook鉤子函數的詳細內容,更多請關注少兒編程網其它相關文章!YqI少兒編程網-Scratch_Python_教程_免費兒童編程學習平臺

預約試聽課

已有385人預約都是免費的,你也試試吧...

国产乱子伦高清露脸对白-国产精品欧美久久久久天天影视-国产91视频一区-亚洲欧美日产综合在线网-黄视频网站在线看-国产欧美亚洲精品第1页-亚洲www在线-大学生女人三级在线播放-日本在线视频www鲁啊鲁-国产成人精品一区二区仙踪林-69精品欧美一区二区三区-成人欧美亚洲-日本污污网站-中国妞xxxhd露脸偷拍视频-国产精品aⅴ在线观看-精品中文字幕在线

        喜爱夜蒲2在线| 黄色国产一级视频| 免费黄色福利视频| 91视频 - 88av| 国产91porn| 欧美与动交zoz0z| 天堂av在线8| 久久6免费视频| 两性午夜免费视频| 成人免费黄色av| 亚洲高潮无码久久| 成人在线国产视频| 18岁网站在线观看| 欧美日韩在线不卡视频| 粗暴91大变态调教| 婷婷免费在线观看| 免费成人深夜夜行网站视频| 黄色免费高清视频| 伊人网在线免费| 男人日女人下面视频| 少妇高清精品毛片在线视频| 五月婷婷激情久久| 国产精品中文久久久久久| 中文字幕免费高| 欧美久久久久久久久久久久久| 日本www在线视频| 成人性生生活性生交12| 亚洲第一色av| 久久久久久久中文| 一区二区三区 欧美| 小早川怜子一区二区三区| 国产精品无码电影在线观看| 国产极品粉嫩福利姬萌白酱| 亚洲成人福利在线观看| 国产一区二区片| 欧美日韩在线成人| 黑人巨茎大战欧美白妇| a在线视频观看| 午夜在线视频免费观看| 人妻少妇被粗大爽9797pw| 日本黄色福利视频| 亚洲国产精品成人天堂| 天天摸天天舔天天操| 国产在线精品91| 亚洲黄色片免费| 欧美 国产 小说 另类| 青青草视频国产| 中文字幕 91| 日韩在线xxx| 成人免费在线网| 黄色小视频大全| 污污网站免费看| 蜜臀视频一区二区三区| 日韩小视频在线播放| 桥本有菜av在线| 在线观看免费黄网站| 37pao成人国产永久免费视频| 涩涩网站在线看| 中文字幕国产传媒| 日韩中文字幕免费在线| 精品无码国模私拍视频| 亚洲一区二区三区四区精品| 高潮一区二区三区| 中文av一区二区三区| 中文字幕第80页| 人妻丰满熟妇av无码区app| 日韩中文字幕在线免费| 国产欧美日韩小视频| 午夜探花在线观看| 亚洲一区二区三区四区精品| 国产又爽又黄ai换脸| 日本一二三区在线| 自拍一级黄色片| 潘金莲一级淫片aaaaa免费看| 日韩av自拍偷拍| 亚洲国产欧美91| 神马午夜伦理影院| 日韩在线视频在线| 欧美久久久久久久久久久久久| 男人的天堂狠狠干| 欧美成人黑人猛交| 少妇激情一区二区三区| 午夜剧场在线免费观看| 欧美午夜精品理论片| 亚洲国产精品女人| 欧美a v在线播放| 国产免费视频传媒| 天堂网成人在线| 国产精品无码电影在线观看 | 五月丁香综合缴情六月小说| 日韩一级特黄毛片| 熟女少妇在线视频播放| 免费无码av片在线观看| 在线观看免费视频污| 热久久精品免费视频| 四虎永久在线精品无码视频| 无码人妻丰满熟妇区五十路百度| 97超碰人人澡| 蜜臀av性久久久久蜜臀av| 中文字幕日韩精品无码内射| 欧美日韩黄色一级片| 黑人粗进入欧美aaaaa| 成人综合视频在线| 99久久久精品视频| 男人的天堂99| 深夜黄色小视频| 成年人网站国产| 六月激情综合网| 欧美午夜精品理论片| 成人在线播放网址| 亚洲国产高清av| 亚欧精品在线视频| 国产无限制自拍| 国产成人黄色网址| 久久精品国产sm调教网站演员| 免费男同深夜夜行网站| 无码人妻精品一区二区蜜桃百度| www.日本一区| 成人一级片网站| 久久久精品三级| 最新av在线免费观看| 欧美日韩一区二区在线免费观看| 北条麻妃亚洲一区| 亚洲天堂av一区二区三区| 亚洲五码在线观看视频| 欧美中日韩在线| 免费看一级大黄情大片| 一女二男3p波多野结衣| 久久久久99精品成人片| 国产经典久久久| 国产探花在线观看视频| 91制片厂毛片| 污视频免费在线观看网站| 国产一级片黄色| 国产精品拍拍拍| 亚洲精品视频导航| 午夜久久福利视频| 国产色视频在线播放| www.超碰com| 少妇一级淫免费放| 99热这里只有精品在线播放| 性生交免费视频| 99中文字幕在线| 亚洲一区二区三区四区精品| 一区二区三区日韩视频| 亚洲av毛片在线观看| 日韩免费在线观看av| 亚洲精品少妇一区二区| 岛国大片在线播放| www.四虎成人| 99日在线视频| cao在线观看| 91国产精品视频在线观看| 三级黄色片播放| 精品久久久久久久久久中文字幕| 国产一区二区在线视频播放| 国产激情在线观看视频| 91网址在线观看精品| 一级性生活视频| 日本一极黄色片| 九九热视频免费| 少妇性饥渴无码a区免费| 999香蕉视频| 久久最新免费视频| www.国产区| 男女啪啪免费观看| 国产原创精品在线| 很污的网站在线观看| 久久精品影视大全| 给我免费播放片在线观看| 天天干天天操天天玩| 免费看国产曰批40分钟| 又色又爽又黄视频| 国产精品-区区久久久狼| 国产日本欧美在线| 欧美一级在线看| 九九久久九九久久| 老司机午夜性大片| 国产精品专区在线| 欧美h视频在线观看| 亚欧在线免费观看| 黄色网页免费在线观看| 国产精品av免费| 日韩av片网站| 乱子伦视频在线看| 日韩视频免费播放| 日韩一二区视频| 美国av在线播放| caoporm在线视频| 爱情岛论坛成人| 午夜视频在线瓜伦| 97av视频在线观看| 蜜臀av无码一区二区三区| 日韩精品福利片午夜免费观看| 日本中文字幕精品—区二区| 国产aaaaa毛片| 久久久久狠狠高潮亚洲精品| 成品人视频ww入口| 青青青青草视频| 欧美成人高潮一二区在线看|