Я смотрю на некоторый код Python, который использовал @
символ, но я понятия не имею, что он делает. Я также не знаю, что искать, так как поиск документов Python или Google не возвращает релевантные результаты, когда @
символ включен.
python
syntax
python-decorators
AJ00200
источник
источник
пример
Это показывает , что
function
/method
/class
вы определяете после декоратор только в основном передается какargument
кfunction
/method
сразу после@
знака.Первое наблюдение
Микрофрейм Flask с самого начала представляет декораторов в следующем формате:
Это в свою очередь означает:
Осознание этого, наконец, позволило мне почувствовать себя в мире с Flask.
источник
app.route("/")
: эта функция возвращает функцию, которую вы вызываете сhello()
аргументомapp.route("/", hello)
сразу после определенияhello
, или даже определятьhello
как лямбду в аргументах дляapp.route
? (Последний пример обычен для Node.jshttp.Server
и Express-маршрутов.)Этот фрагмент кода:
Эквивалентно этому коду:
В определение декоратора вы можете добавить некоторые измененные вещи, которые не будут возвращены функцией в обычном режиме.
источник
В Python 3.5 вы можете перегружаться
@
как оператор. Он называется как__matmul__
, потому что он предназначен для умножения матриц, но это может быть что угодно. Смотрите PEP465 для деталей.Это простая реализация умножения матриц.
Этот код дает:
источник
@=
оператор (на месте), который есть__imatmul__
.__add__
и__sub__
связан с + и - соответственно, но никогда раньше не слышал о@
знаке. Есть ли какие-нибудь другие, скрывающиеся там?Что символ «at» (@) делает в Python?
Короче говоря, он используется в синтаксисе декоратора и для умножения матриц.
В контексте декораторов этот синтаксис:
эквивалентно этому:
В контексте умножения матриц
a @ b
вызываетa.__matmul__(b)
- делает этот синтаксис:эквивалентно
а также
эквивалентно
где
dot
, например, функция умножения матриц иa
иb
матрицы.Как вы можете обнаружить это самостоятельно?
Если вы хотите получить достаточно полное представление о том, что делает конкретный фрагмент синтаксиса Python, посмотрите непосредственно на файл грамматики. Для ветки Python 3:
Мы можем видеть здесь, что
@
используется в трех контекстах:Синтаксис декоратора:
Поиск в Google по запросу «документы-декораторы Python» дает в качестве одного из лучших результатов раздел «Сложные заявления» в «Справочнике по языку Python». Прокрутив вниз до раздела, посвященного определениям функций , который мы можем найти, выполнив поиск по слову «decorator», мы увидим, что ... есть что почитать. Но слово «декоратор» - это ссылка на глоссарий , который говорит нам:
Итак, мы видим, что
семантически совпадает с:
Они не совсем одинаковы, потому что Python оценивает выражение foo (которое может быть точечным поиском и вызовом функции) перед bar с
@
синтаксисом decorator ( ), но оценивает выражение foo после bar в другом случае.(Если это различие имеет значение в значении вашего кода, вам следует пересмотреть то, что вы делаете со своей жизнью, потому что это будет патологически.)
С накоплением декораторов
Если мы вернемся к документации по синтаксису определения функции, мы увидим:
Это демонстрация того, что мы можем сначала вызвать функцию, которая является декоратором, а также декораторы стека. Функции в Python являются объектами первого класса - это означает, что вы можете передавать функцию в качестве аргумента другой функции и возвращать функции. Декораторы делают обе эти вещи.
Если мы укладываем декораторы, функция, как определено, передается сначала декоратору непосредственно над ним, затем следующему и так далее.
Это о суммировании использования
@
в контексте декораторов.Оператор,
@
В разделе лексического анализа справочника по языку у нас есть раздел об операторах , который включает в себя
@
, что делает его также оператором:и на следующей странице, Модель данных, у нас есть раздел Эмуляция числовых типов ,
И мы видим, что
__matmul__
соответствует@
. Если мы ищем в документации «matmul», мы получаем ссылку на « Что нового в Python 3.5» с «matmul» под заголовком «PEP 465 - Специальный инфиксный оператор для умножения матриц».(Итак, теперь мы узнаем, что
@=
это версия на месте). Это также объясняет:Хотя этот оператор может быть перегружен для выполнения практически чего угодно
numpy
, например, мы будем использовать этот синтаксис для вычисления внутреннего и внешнего произведения массивов и матриц:Умножение матрицы на месте:
@=
Исследуя предыдущее использование, мы узнаем, что существует также умножение матрицы на месте. Если мы попытаемся использовать его, мы можем обнаружить, что он еще не реализован для numpy:
Когда это будет реализовано, я ожидаю, что результат будет выглядеть так:
источник
Символ @ - это синтаксический сахарный питон, который можно использовать
decorator
,чтобы перефразировать вопрос: это именно то, что декоратор делает в Python?
Проще говоря,
decorator
вы можете изменить определение данной функции, не касаясь ее внутренней части (это замыкание).Это тот самый случай, когда вы импортируете замечательную упаковку от третьего лица Вы можете визуализировать это, вы можете использовать это, но вы не можете коснуться его самого и его сердца.
Вот быстрый пример,
предположим , что я определяю
read_a_book
функцию на IpythonВидите ли, я забыл добавить имя к нему.
Как решить такую проблему? Конечно, я мог бы переопределить функцию как:
Тем не менее, что делать, если мне не разрешено манипулировать исходной функцией, или если есть тысячи таких функций для обработки.
Решите проблему, думая иначе и определите новую функцию
Тогда используйте это.
Тада, понимаешь, я исправил,
read_a_book
не касаясь его внутреннего закрытия. Ничто не мешает мне экипироватьсяdecorator
.Как насчет
@
@add_a_book
это модный и удобный способ сказатьread_a_book = add_a_book(read_a_book)
, что это синтаксический сахар, в этом нет ничего более причудливого.источник
Если вы имеете в виду какой-то код в записной книжке Python, который использует библиотеку Numpy , тогда
@ operator
подразумевается Matrix Multiplication . Например:источник
Начиная с Python 3.5, «@» используется в качестве специального символа инфикса для MATRIX MULTIPLICATION (PEP 0465 - см. Https://www.python.org/dev/peps/pep-0465/ )
источник
В Python были добавлены декораторы для облегчения чтения и понимания переноса функций и методов (функция, которая получает функцию и возвращает расширенную). Исходный вариант использования должен был иметь возможность определять методы как методы класса или статические методы в начале их определения. Без синтаксиса декоратора это потребовало бы довольно редкого и повторяющегося определения:
Если синтаксис декоратора используется для той же цели, код становится короче и проще для понимания:
Общий синтаксис и возможные реализации
Декоратор обычно является именованным объектом ( лямбда-выражения не допускаются ), который принимает один аргумент при вызове (это будет декорированная функция) и возвращает другой вызываемый объект. «Callable» используется здесь вместо «function» с преднамеренностью. Хотя декораторы часто обсуждаются в области методов и функций, они не ограничиваются ими. Фактически, все, что можно вызвать (любой объект, который реализует метод _call__, считается вызываемым), можно использовать в качестве декоратора, и часто возвращаемые ими объекты являются не простыми функциями, а большим количеством экземпляров более сложных классов, реализующих свой собственный метод __call_.
Синтаксис декоратора - это просто синтаксический сахар . Рассмотрим следующее использование декоратора:
Это всегда можно заменить явным вызовом декоратора и переназначением функции:
Тем не менее, последний менее читабелен и также очень трудно понять, если несколько декораторов используются для одной функции. Декораторы могут использоваться несколькими различными способами, как показано ниже:
Как функция
Есть много способов написания пользовательских декораторов, но самый простой способ - написать функцию, которая возвращает подфункцию, которая оборачивает исходный вызов функции.
Общие шаблоны выглядят следующим образом:
Как класс
Хотя декораторы почти всегда могут быть реализованы с использованием функций, в некоторых ситуациях использование пользовательских классов является лучшим вариантом. Это часто верно, когда декоратор нуждается в сложной параметризации или зависит от конкретного состояния.
Общий шаблон для непараметризованного декоратора как класса выглядит следующим образом:
Параметризация декораторов
В реальном коде часто возникает необходимость использовать декораторы, которые можно параметризовать. Когда функция используется в качестве декоратора, тогда решение простое - необходимо использовать второй уровень упаковки. Вот простой пример декоратора, который повторяет выполнение декорированной функции указанное количество раз при каждом ее вызове:
Определенный таким образом декоратор может принимать параметры:
Обратите внимание, что даже если параметризованный декоратор имеет значения по умолчанию для своих аргументов, скобки после его имени обязательны. Правильный способ использования предыдущего декоратора с аргументами по умолчанию заключается в следующем:
Наконец, давайте посмотрим декораторы со свойствами.
свойства
Свойства предоставляют встроенный тип дескриптора, который знает, как связать атрибут с набором методов. Свойство принимает четыре необязательных аргумента: fget, fset, fdel и doc. Последний может быть предоставлен для определения строки документации, которая связана с атрибутом, как если бы это был метод. Вот пример класса Rectangle, которым можно управлять либо прямым доступом к атрибутам, которые хранят две угловые точки, либо используя свойства width и height:
Лучший синтаксис для создания свойств - использование свойства в качестве декоратора. Это сократит количество сигнатур методов внутри класса и сделает код более читабельным и обслуживаемым . С декораторами вышеприведенный класс становится:
источник
Сказать, что другие имеют по-другому: да, это декоратор.
В Python это похоже на:
Это может использоваться для всех видов полезных вещей, ставших возможными, потому что функции являются объектами и просто необходимы только инструкции.
источник
@ Символ также используется для доступа к переменным внутри plydata / панды dataframe запроса
pandas.DataFrame.query
. Пример:источник
Это указывает на то, что вы используете декоратор. Вот пример Брюса Экеля из 2008 года.
источник