Недавно я услышал термин «крючок», когда разговаривал с некоторыми людьми о программе, которую я писал. Я не уверен, что именно подразумевает этот термин, хотя из разговора я сделал вывод, что ловушка - это тип функции. Я искал определение, но не смог найти хорошего ответа. Может ли кто-нибудь дать мне представление о том, что обычно означает этот термин, и, возможно, небольшой пример для иллюстрации определения?
13 ответов
По сути, это место в коде, которое позволяет вам подключиться к модулю, чтобы либо обеспечить другое поведение, либо отреагировать, когда что-то происходит.
Много ответов, но нет примеров, поэтому добавляем фиктивный: следующий complicated_func
предлагает два крючка для изменения его поведения
from typing import List, Callable
def complicated_func(
lst: List[int], hook_modify_element: Callable[[int], int], hook_if_negative=None
) -> int:
res = sum(hook_modify_element(x) for x in lst)
if res < 0 and hook_if_negative is not None:
print("Returning negative hook")
return hook_if_negative
return res
def my_hook_func(x: int) -> int:
return x * 2
if __name__ == "__main__":
res = complicated_func(
lst=[1, 2, -10, 4],
hook_modify_element=my_hook_func,
hook_if_negative=0,
)
print(res)
Ловушка - это функция, предоставляемая программным обеспечением для пользователей этого программного обеспечения, позволяющая при определенных обстоятельствах вызывать свой собственный код. Этот код может дополнять или заменять текущий код.
В былые времена, когда компьютеры были по-настоящему личными, а вирусы были менее распространены (я говорю о 80-х), для вызова вашего кода было достаточно просто установить патч для самого программного обеспечения операционной системы. Я помню, как писал расширение для языка Applesoft BASIC на Apple II, которое просто подключало мой код к интерпретатору BASIC, вводя вызов моего кода до того, как какая-либо строка была обработана.
На некоторых компьютерах были заранее спроектированные перехватчики, одним из примеров которых является поток ввода-вывода на Apple II. Он использовал такой крючок для внедрения всей дисковой подсистемы (ПЗУ Apple II изначально создавались в те дни, когда кассеты были основным носителем информации для ПК). Вы управляли дисками с помощью печати кода ASCII 4 (CTRL-D
), за которым следовала команда, которую вы хотели выполнить, затем CR
, и она была перехвачена дисковой подсистемой , который подключился к процедурам печати Apple ROM.
Так, например, строки:
PRINT CHR(4);"CATALOG"
PRINT CHR(4);"IN#6"
Отобразит содержимое диска, а затем повторно инициализирует машину. Это позволяло использовать такие уловки, как защита ваших программ BASIC, задав в первой строке следующую строку:
123 REM XIN#6
Затем с помощью POKE
вставить символ CTRL-D
вместо X
. Затем любой, кто попытается перечислить ваш источник, отправит последовательность повторной инициализации через процедуры вывода, где дисковая подсистема обнаружит ее.
Часто нам приходилось прибегать к подобным уловкам, чтобы добиться желаемого поведения.
В настоящее время, когда операционная система более безопасна, она сама предоставляет средства для перехвата, поскольку вам больше не нужно изменять операционную систему «в полете» или на диске.
Они существуют уже давно . Они были у мэйнфреймов (называемые выходами), и даже сейчас многие программы для мэйнфреймов используют эти возможности. Например, бесплатная система управления исходным кодом, поставляемая с z / OS (называемая SCLM), позволяет полностью заменить подсистему безопасности, просто поместив свой собственный код в выход.
В общем смысле, «ловушка» - это то, что позволяет вам, программисту, просматривать и / или взаимодействовать, и / или изменять что-то, что уже происходит в системе / программе.
Например, Drupal CMS предоставляет разработчикам ловушки, позволяющие им выполнять дополнительные действия после создания «узла содержимого». Если разработчик не реализует ловушку, узел создается обычным образом. Если разработчик реализует ловушку, он может запускать дополнительный код при создании узла. Этот код может делать что угодно, включая откат и / или изменение исходного действия. Он также может делать что-то совершенно не связанное с созданием узла.
Обратный вызов можно рассматривать как особый вид ловушки. Реализуя функцию обратного вызова в системе, эта система позволяет вам вызывать некоторый дополнительный код после завершения действия. Однако подключение (как общий термин) не ограничивается обратными вызовами.
Другой пример. Иногда веб-разработчики называют имена классов и / или идентификаторы элементов хуками. Это потому, что, поместив идентификатор / имя класса в элемент, они могут затем использовать Javascript для изменения этого элемента или «подключиться» к документу страницы. (это растягивает значение, но оно широко используется и заслуживает упоминания)
Просто сказал:
Хук - это средство выполнения пользовательского кода (функции) до, после или вместо существующего кода. Например, может быть написана функция для «подключения» к процессу входа в систему для выполнения функции Captcha перед продолжением обычного процесса входа в систему.
Хуки - это категория функций, которая позволяет базовому коду вызывать код расширения. Это может быть полезно в ситуациях, когда основной разработчик хочет предложить расширяемость, не раскрывая свой код.
Одно из применений хуков - это разработка модов для видеоигр. Игра может не позволять разработчикам модов расширять базовую функциональность, но разработчики основной библиотеки модов могут добавлять хуки. С помощью этих хуков независимые разработчики могут вызывать свой собственный код при любом желаемом событии, таком как загрузка игры, обновление инвентаря, взаимодействие сущностей и т. Д.
Распространенный метод реализации - предоставить функции пустой список обратных вызовов, а затем предоставить возможность расширения списка обратных вызовов. Базовый код всегда будет вызывать функцию в одно и то же время, но с пустым списком обратных вызовов функция ничего не делает. Это сделано намеренно.
Таким образом, третья сторона имеет возможность написать дополнительный код и добавить свой новый обратный вызов в список обратных вызовов ловушки. Имея не более чем ссылку на доступные хуки, они имеют расширенную функциональность с минимальным риском для базовой системы.
Хуки не позволяют разработчикам делать то, что нельзя сделать с другими структурами и интерфейсами. Их выбор следует делать с учетом задачи и пользователей (сторонних разработчиков).
Для пояснения: ловушка допускает расширение и может быть реализована с помощью обратных вызовов. Обратные вызовы обычно представляют собой не более чем указатель на функцию; вычисленный адрес функции. Похоже, что в других ответах / комментариях есть путаница.
Перехват в программировании - это метод, использующий так называемые перехватчики для создания цепочки процедур в качестве обработчика событий. .
Хук обозначает место в коде, где вы отправляете событие определенного типа, и если это событие было зарегистрировано ранее с соответствующей функцией для обратного вызова, то оно будет обрабатываться этой зарегистрированной функцией, иначе ничего не произойдет.
Ловушки могут быть выполнены при обнаружении некоторого условия. например некоторые переменные изменяются, вызывается какое-то действие или происходит какое-то событие. хуки могут вмешиваться в процесс и изменять вещи или реагировать на изменения.
Цепочка хуков - это набор функций, в которых каждая функция вызывает следующую. Что важно в цепочке перехватчиков, так это то, что программист может добавить в цепочку еще одну функцию во время выполнения. Один из способов сделать это - найти известное место, где хранится адрес первой функции в цепочке. Затем вы сохраняете значение этого указателя на функцию и перезаписываете значение по начальному адресу адресом функции, которую хотите вставить в цепочку ловушек. Затем функция вызывается, выполняет свое дело и вызывает следующую функцию в цепочке (если вы не решите иначе). Естественно, существует ряд других способов создания цепочки перехватчиков, от записи непосредственно в память до использования средств метапрограммирования таких языков, как Ruby или Python.
Примером цепочки перехватчиков является способ обработки сообщений приложением MS Windows. Каждая функция в цепочке обработки либо обрабатывает сообщение, либо отправляет его следующей функции в цепочке.
В системе управления контентом Drupal «крючок» имеет относительно конкретное значение. Когда происходит внутреннее событие (например, создание контента или вход пользователя), модули могут реагировать на событие, реализуя специальную функцию «ловушки». Это делается с помощью соглашения об именах - [your-plugin-name] _user_login (), например, для события User Login.
Из-за этого соглашения базовые события называются «хуками» и появляются с такими именами, как «hook_user_login» и «hook_user_authenticate ()» в документации API Drupal.
Короче говоря, вы можете изменить код вызова API, например MessageBox
, чтобы он выполнял другую функцию, отредактированную вами (глобально будет работать в масштабе всей системы, локально будет работать в масштабе всего процесса).
Часто перехват относится к перехвату сообщений Win32 или эквивалентам Linux / OSX, но в более общем смысле перехватчик - это просто уведомление другого объекта / окна / программы / и т. д. о том, что вы хотите получать уведомления, когда происходит указанное действие. Например: все окна в системе уведомляют вас о своем закрытии.
Как правило, перехват в некоторой степени опасен, поскольку выполнение его без понимания того, как оно влияет на систему, может привести к нестабильности или, как минимум, к неожиданному поведению. Он также может быть ОЧЕНЬ полезным при определенных обстоятельствах, подумал я. Например: FRAPS использует его, чтобы определить, в каких окнах должен отображаться счетчик FPS.
Похожие вопросы
Связанные вопросы
Новые вопросы
hook
Под ловушкой понимается замена или расширение поведения системы или приложения по умолчанию пользовательским поведением для определенного события. Для клавиатурных хуков предпочитайте тег [keyhook]. Для перехвата git используйте только тег [githooks]. Для перехвата веб-сервисов используйте вместо этого тег [webhooks].
click
), существует событиеonbeforeunload
. Похоже, что обратный вызов будет вызван перед фактическим событием. Так технически это событие замаскировано за крючок? Вызываются ли обработчики ловушек до, вместо или после основной операции? ... Я считаю, что между крючком и событием есть несколько отличий. Хук выглядит как низкоуровневое вмешательство, а событие похоже на ограниченную версию ловушки. Почему об этом никто не говорит? Кто-то просветит нас.