functools — Higher-order functions and operations on callable objects¶
The functools module is for higher-order functions: functions that act on or return other functions. In general, any callable object can be treated as a function for the purposes of this module.
The functools module defines the following functions:
@ functools. cache ( user_function ) ¶
Simple lightweight unbounded function cache. Sometimes called “memoize”.
Returns the same as lru_cache(maxsize=None) , creating a thin wrapper around a dictionary lookup for the function arguments. Because it never needs to evict old values, this is smaller and faster than lru_cache() with a size limit.
The cache is threadsafe so that the wrapped function can be used in multiple threads. This means that the underlying data structure will remain coherent during concurrent updates.
It is possible for the wrapped function to be called more than once if another thread makes an additional call before the initial call has been completed and cached.
New in version 3.9.
Transform a method of a class into a property whose value is computed once and then cached as a normal attribute for the life of the instance. Similar to property() , with the addition of caching. Useful for expensive computed properties of instances that are otherwise effectively immutable.
The mechanics of cached_property() are somewhat different from property() . A regular property blocks attribute writes unless a setter is defined. In contrast, a cached_property allows writes.
The cached_property decorator only runs on lookups and only when an attribute of the same name doesn’t exist. When it does run, the cached_property writes to the attribute with the same name. Subsequent attribute reads and writes take precedence over the cached_property method and it works like a normal attribute.
The cached value can be cleared by deleting the attribute. This allows the cached_property method to run again.
Note, this decorator interferes with the operation of PEP 412 key-sharing dictionaries. This means that instance dictionaries can take more space than usual.
Also, this decorator requires that the __dict__ attribute on each instance be a mutable mapping. This means it will not work with some types, such as metaclasses (since the __dict__ attributes on type instances are read-only proxies for the class namespace), and those that specify __slots__ without including __dict__ as one of the defined slots (as such classes don’t provide a __dict__ attribute at all).
If a mutable mapping is not available or if space-efficient key sharing is desired, an effect similar to cached_property() can also be achieved by stacking property() on top of lru_cache() . See How do I cache method calls? for more details on how this differs from cached_property() .
New in version 3.8.
Transform an old-style comparison function to a key function . Used with tools that accept key functions (such as sorted() , min() , max() , heapq.nlargest() , heapq.nsmallest() , itertools.groupby() ). This function is primarily used as a transition tool for programs being converted from Python 2 which supported the use of comparison functions.
A comparison function is any callable that accepts two arguments, compares them, and returns a negative number for less-than, zero for equality, or a positive number for greater-than. A key function is a callable that accepts one argument and returns another value to be used as the sort key.
For sorting examples and a brief sorting tutorial, see Sorting HOW TO .
New in version 3.2.
Decorator to wrap a function with a memoizing callable that saves up to the maxsize most recent calls. It can save time when an expensive or I/O bound function is periodically called with the same arguments.
The cache is threadsafe so that the wrapped function can be used in multiple threads. This means that the underlying data structure will remain coherent during concurrent updates.
It is possible for the wrapped function to be called more than once if another thread makes an additional call before the initial call has been completed and cached.
Since a dictionary is used to cache results, the positional and keyword arguments to the function must be hashable .
Distinct argument patterns may be considered to be distinct calls with separate cache entries. For example, f(a=1, b=2) and f(b=2, a=1) differ in their keyword argument order and may have two separate cache entries.
If user_function is specified, it must be a callable. This allows the lru_cache decorator to be applied directly to a user function, leaving the maxsize at its default value of 128:
If maxsize is set to None , the LRU feature is disabled and the cache can grow without bound.
If typed is set to true, function arguments of different types will be cached separately. If typed is false, the implementation will usually regard them as equivalent calls and only cache a single result. (Some types such as str and int may be cached separately even when typed is false.)
Note, type specificity applies only to the function’s immediate arguments rather than their contents. The scalar arguments, Decimal(42) and Fraction(42) are be treated as distinct calls with distinct results. In contrast, the tuple arguments (‘answer’, Decimal(42)) and (‘answer’, Fraction(42)) are treated as equivalent.
The wrapped function is instrumented with a cache_parameters() function that returns a new dict showing the values for maxsize and typed. This is for information purposes only. Mutating the values has no effect.
To help measure the effectiveness of the cache and tune the maxsize parameter, the wrapped function is instrumented with a cache_info() function that returns a named tuple showing hits, misses, maxsize and currsize.
The decorator also provides a cache_clear() function for clearing or invalidating the cache.
The original underlying function is accessible through the __wrapped__ attribute. This is useful for introspection, for bypassing the cache, or for rewrapping the function with a different cache.
The cache keeps references to the arguments and return values until they age out of the cache or until the cache is cleared.
If a method is cached, the self instance argument is included in the cache. See How do I cache method calls?
An LRU (least recently used) cache works best when the most recent calls are the best predictors of upcoming calls (for example, the most popular articles on a news server tend to change each day). The cache’s size limit assures that the cache does not grow without bound on long-running processes such as web servers.
In general, the LRU cache should only be used when you want to reuse previously computed values. Accordingly, it doesn’t make sense to cache functions with side-effects, functions that need to create distinct mutable objects on each call, or impure functions such as time() or random().
Example of an LRU cache for static web content:
Example of efficiently computing Fibonacci numbers using a cache to implement a dynamic programming technique:
Функции высшего порядка — Python: Функции
Функции высшего порядка — это важная концепция в Python. В Python все является объектом, включая функции. Это означает, что функции можно передавать в качестве аргументов другим функциям как и любой другой объект.
Функции, которые можно передавать в качестве аргументов или возвращать из других функций, известны как объекты первого класса или граждане первого класса.
В этом уроке мы научимся работать с объектами первого класса, функциями высшего порядка и лямбда-функциями.
Объекты первого класса
В Python функции являются объектами первого класса. Это означает, что их можно передавать в качестве аргументов другим функциям, возвращать значения из функций и хранить в переменных или структурах данных как любой другой объект. Это позволяет использовать функции как строительные блоки для более сложных программ.
Напишем пример, чтобы посмотреть, как функции используются в качестве объекта первого класса:
В этом примере мы определяем функцию hello , которая принимает один аргумент и печатает приветствие. Затем мы присваиваем функцию переменной greeting_function и вызываем ее с аргументом.
Рассмотрим другой пример с передачей функции в качестве аргумента другой функции:
В этом примере функция apply_function принимает в качестве аргументов список чисел и функцию. Функция apply_function применяет переданную функцию к каждому числу в списке и возвращает новый измененный список. Функция square возводит число в квадрат, и используется в качестве аргумента функции apply_function .
Объекты первого класса также позволяют возвращать функции из другой функции:
В этом примере функция make_multiplier принимает число n и возвращает новую функцию, которая умножает свой аргумент на n . Затем эта функция применяется, чтобы создать две новые функции times_2 и times_3 , которые умножают свой аргумент на 2 и 3 соответственно. В итоге вызывается функция с аргументом 5, чтобы увидеть их результаты.
Функции высшего порядка
Функции, которые принимают другие функции в качестве аргументов и/или возвращают функции в качестве результатов, называются функциями высшего порядка или ФВП. Их можно использовать для инкапсуляции многократно используемого поведения и создания более абстрактного кода, о котором легче рассуждать.
Например, встроенные функции map и filter в Python являются функциями высшего порядка, которые работают с итерируемыми объектами и применяют функцию к каждому элементу итерируемого объекта.
Рассмотрим следующий пример функции высшего порядка:
Вывод будет следующим:
Этот код использует функцию repeat() для многократного вызова функции hello() .
Рассмотрим другой пример с возвратом функции:
В этом примере в теле функции double создается функция inner и возвращается в роли результата. Так как вызов double возвращает функцию, мы можем сразу сделать второй вызов ( (3) ). Он уже даст результат двойного применения исходной функции к аргументу.
Имя inner довольно часто используется, чтобы называть функции, которые создаются на лету внутри внешней функции.
Но мы могли бы и не вызвать функцию-значение сразу, а вместо этого сохранить в переменную:
При выводе значения ссылки multiply_by_25 отображается double.<locals>.inner — та самая созданная на лету функция inner . И в случае multiply_by_625 функция называется inner , но адрес в памяти другой — большое шестнадцатеричное число после "at".
Одним из полезных применений функций высшего порядка является использование их для определения анонимных функций — лямбда-функций.
Лямбда-функции
В Python лямбда функция — это небольшая анонимная функция, которая может быть определена без имени. Лямбда-функции часто используются там, где требуется небольшая, одноразовая функция. Синтаксис для определения лямбда-функции в Python следующий:
Здесь arguments — это список входных аргументов функции, который разделен запятыми. А expression — это тело функции, значение которой возвращает лямбда-функция.
Например, лямбда-функция, которая принимает два аргумента и возвращает их сумму, может быть определена следующим образом:
Это создает лямбда-функцию, которая принимает два аргумента x и y и возвращает их сумму. Затем лямбда-функцию можно вызывать как любую другую функцию:
Лямбда-функции также можно использовать в сочетании с другими функциями, такими как map , filter и reduce . С их помощью можно создать краткий и выразительный код. Например, следующий код использует лямбда-функцию с функцией map для возведения в квадрат каждого элемента списка:
В этом коде лямбда-функция lambda x: x**2 передается в качестве первого аргумента функции map . Это создает новый объект-итератор, который применяет лямбда-функцию к каждому элементу списка numbers . В результате получается новый список квадратных чисел.
Лямбда-функции — мощный инструмент в Python для создания небольших анонимных функций, которые можно использовать в самых разных контекстах. Однако их следует использовать с осторожностью, поскольку их лаконичный синтаксис иногда может затруднить чтение и понимание кода.
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
Functools – сила функций высшего порядка в Python

В стандартной библиотеке Python есть множество замечательных модулей, которые помогают делать ваш код чище и проще, и functools определенно является одним из них. В этом модуле есть множество полезных функций высшего порядка, которые можно использовать для кэширования, перегрузки, создания декораторов и в целом для того, чтобы делать код более функциональным, поэтому давайте отправимся на экскурсию по этому модулю и посмотрим, что он может нам предложить.
Кэширование
Давайте начнем с самых простых, но довольно мощных функций модуля functools . Начнем с функций кэширования (а также декораторов) — lru_cache , cache и cached_property . Первая из них — lru_cache предоставляет кэш последних результатов выполнения функций, или другими словами, запоминает результат их работы:
В этом примере мы делаем GET-запросы и кэшируем их результаты (до 32 результатов) с помощью декоратора @lru_cache . Чтобы увидеть, действительно ли кэширование работает, можно проверить информацию о кэше функции, с помощью метода cache_info , который показывает количество удачных и неудачных обращений в кэш. Декоратор также предоставляет методы clear_cache и cache_parameters для аннулирования кэшированных результатов и проверки параметров, соответственно.
Если вам нужно более детализированное кэширование, можете включить необязательный аргумент typed=true , что позволяет кэшировать аргументы разных типов по отдельности.
Еще один декоратор для кэширования в functools – это функция, которая называется просто cache . Она является простой оберткой lru_cache , которая опускает аргумент max_size , уменьшая его, и не удаляет старые значения.
Еще один декоратор, который вы можете использовать для кэширования – это cached_property . Как можно догадаться из названия, он используется для кэширования результатов атрибутов класса. Механика очень полезная, если у вас есть свойство, которое дорого вычислять, но оно при этом остается неизменным.
Этот простой пример показывает. Как можно использовать cached_property , например, для кэширования отрисованной HTML — страницы, которая должна снова и снова показываться пользователю. То же самое можно сделать для определенных запросов к базе данных или долгих математических вычислений.
Еще одна прелесть cached_property в том, что он запускается только при поиске, поэтому позволяет нам менять значение атрибута. После изменения атрибута закэшированное ранее значение меняться не будет, вместо этого будет вычислено и закэшировано новое значение. А еще кэш можно очистить, и все, что нужно для этого сделать – это удалить атрибут.
Я хочу закончить этот раздел предостережением относительно всех вышеперечисленных декораторов – не используйте их, если у вашей функции есть какие-то побочные эффекты или если она при каждом вызове создает изменяемые объекты, поскольку это явно не те функции, которые вы захотите кэшировать.
Сравнение и упорядочивание
Вероятно, вы уже знаете, что в Python можно реализовать операторы сравнения, такие как < , >= или == , с помощью lt , gt или eq . Однако, может быть довольно неприятно реализовывать каждый из eq , lt , le , gt или ge . К счастью, в functools есть декоратор @total_ordering , который может помочь нам в этом, ведь все, что нам нужно реализовать – это eq и один из оставшихся методов, а остальные декоратор сгенерирует автоматически.
Так мы можем реализовать все расширенные операции сравнения несмотря на то, что руками написали только eq и lt . Наиболее очевидным преимуществом является удобство, которое заключается в том, что не нужно писать все эти дополнительные волшебные метода, но, вероятно, важнее здесь уменьшение количества кода и его лучшая читаемость.
Перегрузка
Вероятно, всех нас учили, что перегрузки в Python нет, но на самом деле есть простой способ реализовать ее с помощью двух функций из functools , а именно singledispatch и/или singledispatchmethod . Эти функции помогают нам реализовать то, что мы бы назвали алгоритмом множественной диспетчеризации, который позволяет динамически типизированным языкам программирования, таким как Python, различать типы во время выполнения.
Учитывая, что перегрузка функций сама по себе является довольно обширной темой, я посвятил отдельную статью singledispatch и singledispatchmethod . Если вы хотите узнать о теме побольше, вы можете прочитать о ней здесь.
Partial
Мы все работаем с различными внешними библиотеками или фреймворками, многие из которых предоставляют функции и интерфейсы, требующие от нас передачи коллбэков, например, для асинхронных операций или прослушивания событий. В этом нет ничего нового, но что, если нам нужно еще и передать некоторые аргументы вместе с коллбэком. Именно здесь и пригодится functools.partial . Можно использовать partial для замораживания некоторых (или всех) аргументов функции, создавая новый объект с упрощенной сигнатурой функции. Запутались? Давайте рассмотрим несколько примеров из практики:
Код выше показывает, как можно использовать partial для передачи функции ( output_result ) вместе с аргументом ( log=logger ) в качестве коллбэка. В этом случае мы воспользуемся multiprocessing.apply_async , которая асинхронно вычисляет результат функции ( concat ) и возвращает результат коллбэка. Однако apply_async всегда будет передавать результат в качестве первого аргумента, и, если мы хотим включить какие-то дополнительные аргументы, как в случае с log=logger , нужно использовать partial .
Мы рассмотрели достаточно продвинутый вариант использования, а более простым примером может быть обычное создание функции, которая пишет в stderr вместо stdout :
С помощью этого простого трюка мы создали новую callable-функцию, которая всегда будет передавать file=sys.stderr в качестве именованного аргумента для вывода, что позволяет нам упростить код и не указывать значение именованного аргумента каждый раз.
И последний хороший пример. Мы можем использовать partial в связке с малоизвестной функцией iter , чтобы создать итератор, передав вызываемый объект и sentinel в iter , что можно применить следующим образом:
Обычно при чтении файла мы хотим итерироваться по строкам, но в случае бинарных данных нам может понадобиться итерироваться по записям фиксированного размера. Сделать это можно, создав вызываемый объект с помощью partial , который считывает указанный чанк данных и передает их в iter для создания итератора. Затем этот итератор вызывает функцию чтения до тех пор, пока не дойдет до конца файла, всегда беря только указанный объем чанка ( RECORD_SIZE ). Наконец, по достижении конца файла возвращается значение sentinel (b») и итерация прекращается.
Декораторы
Мы уже говорили о кое-каких декораторах в прошлых разделах, но не о декораторах для создания еще большего количества декораторов. Одним из таких декораторов является functools.wraps . Чтобы понять зачем он нужен, давайте просто посмотрим на пример:
Этот пример показывает, как можно реализовать простой декоратор. Мы оборачиваем функцию, выполняющую определенную задачу ( actual_func ), внешним декоратором, и она сама становится декоратором, который затем можно применить к другим функциям, например, как в случае с greet . При вызове функции greet вы увидите, что она выводит сообщения как от actual_func , так и свои собственные. Вроде выглядит нормально, не так ли? Но что будет, если мы сделаем так:
Когда мы вызываем имя и документацию декорированной функции, мы понимаем, что они были заменены значениями из функции декоратора. Это плохо, поскольку мы не можем перезаписывать все наши имена функций и документацию каждый раз при использовании какого-либо декоратора. Как же решить эту проблему? Конечно же, с помощью functools.wraps :
Единственная задача функции wraps – это копирование имени, документации, списка аргументов и т.д., для предотвращения перезаписи. Если учесть, что wraps – это тоже декоратор, можно просто добавить его в нашу actual_func , и проблема решена!
Reduce
Последнее, но не менее важное в модуле functools – это reduce . Возможно, из других языков, вы можете знать ее как fold (Haskell). Эта функция берет итерируемый объект и сворачивает (складывает) все его значения в одно. Применений этому множество, например:
Как видно из кода, reduce может упростить или сжать код в одну строку, которая в противном случае была бы намного длиннее. С учетом сказанного злоупотреблять этой функцией только ради сокращения кода, делать ее «умнее» — обычно плохая идея, поскольку она быстро становится страшной и нечитаемой. По этой причине, на мой взгляд, пользоваться ей стоит экономно.
А если помнить, что reduce частенько сокращает все до одной строки, ее отлично можно скомбинировать с partial :
И, наконец, если вам нужен не только итоговый «свернутый» результат, то вы можете использовать accumulate – из другого замечательного модуля itertools . Для вычисления максимума ее можно использовать следующим образом:
Заключение
Как видите, в functools есть множество полезных функций и декораторов, которые могут облегчить вам жизнь, но это лишь верхушка айсберга. Как я говорил вначале, в стандартной библиотеке Python есть множество функций, которые помогают писать код лучше, поэтому, помимо функций, которые мы здесь рассмотрели, вы можете обратить внимание на другие модули, такие как operator или itertools (мою статью об этом модуле вы можете прочитать здесь или просто отправляйтесь в Python Module Index и изучите все, на что обратите внимание, и я просто уверен, что вы найдете там что-то полезное.
Всех желающих приглашаем на онлайн-интенсив «Быстрая разработка JSON API приложений на Flask». На этом уроке мы:
— Познакомимся со спецификацией JSON API;
— Узнаем, что такое сериализация/десериализация данных;
— Узнаем, что такое marshmallow и marshmallow-jsonapi;
— Познакомимся со Swagger;
— Посмотрим на обработку и выдачу связей.
functools-функции высшего порядка и операции над вызываемыми объектами
Модуль functools предназначен для функций высшего порядка: функций, которые действуют или возвращают другие функции. В общем, любой вызываемый объект можно рассматривать как функцию для целей этого модуля.
Модуль functools определяет следующие функции:
Простой легкий неограниченный кеш функций. Иногда называется «запоминание» .
Возвращает то же самое, что и lru_cache(maxsize=None) , создавая тонкую оболочку вокруг поиска по словарю для аргументов функции. Поскольку ему никогда не нужно удалять старые значения, он меньше и быстрее, чем lru_cache() с ограничением размера.
Новинка в версии 3.9.
Преобразуйте метод класса в свойство, значение которого вычисляется один раз, а затем кэшируется как обычный атрибут на время существования экземпляра. Аналогично property() с добавлением кеширования. Полезно для дорогостоящих вычисляемых свойств экземпляров, которые в противном случае фактически неизменяемы.
Механизм cached_property() несколько отличается от property() . Обычный атрибут блоков свойств записывает, если не определен установщик. Напротив, cached_property разрешает запись.
Декоратор cached_property запускается только при поиске и только тогда, когда атрибут с таким именем не существует. При запуске cached_property записывает в атрибут с тем же именем. Последующие операции чтения и записи атрибутов имеют приоритет над методом cached_property и работают как обычный атрибут.
Кешированное значение можно очистить, удалив атрибут. Это позволяет снова запустить метод cached_property .
Обратите внимание, что этот декоратор мешает работе словарей совместного использования ключей PEP 412 . Это означает, что экземпляры словарей могут занимать больше места, чем обычно.
Кроме того, этот декоратор требует, чтобы атрибут __dict__ в каждом экземпляре был изменяемым сопоставлением. Это означает, что он не будет работать с некоторыми типами, такими как метаклассы (поскольку атрибуты __dict__ в экземплярах типов являются прокси-серверами только для чтения для пространства имен класса), и те, которые указывают __slots__ без включения __dict__ в качестве одного из определенных слотов (поскольку такие классы вообще не указывайте атрибут __dict__ ).
Если изменяемое отображение недоступно или если требуется совместное использование ключей с эффективным использованием пространства, эффект, аналогичный cached_property() может быть достигнут с помощью property() стекирования () поверх cache() :
Новинка в версии 3.8.
Преобразуйте функцию сравнения старого стиля в ключевую функцию . Используется с инструментами, которые принимают ключевые функции (такие как sorted() , min() , max() , heapq.nlargest() , heapq.nsmallest() , itertools.groupby() ). Эта функция в основном используется в качестве инструмента перехода для программ, конвертируемых из Python 2, которые поддерживают использование функций сравнения.
Функция сравнения-это любая вызываемая функция,которая принимает два аргумента,сравнивает их и возвращает отрицательное число для меньшего,ноль для равенства или положительное число для большего.Функция ключа-это вызываемая функция,которая принимает один аргумент и возвращает другое значение,используемое в качестве ключа сортировки.
Примеры сортировки и краткое руководство по сортировке см . В разделе Сортировка КАК .
Новинка в версии 3.2.
Декоратор для обертывания функции памяткой вызываемой, которая сохраняет до максимального размера самые последние вызовы. Это может сэкономить время, когда дорогостоящая функция или функция, связанная с вводом-выводом, периодически вызывается с теми же аргументами.
Поскольку для кэширования результатов используется словарь,аргументы позиционирования и ключевые слова функции должны быть хэшируемыми.
Различные шаблоны аргументов можно рассматривать как отдельные вызовы с отдельными записями в кэше. Например, f(a=1, b=2) и f(b=2, a=1) различаются порядком их аргументов ключевого слова и могут иметь две отдельные записи кэша.
Если указана user_function , она должна быть вызываемой. Это позволяет применять декоратор lru_cache непосредственно к пользовательской функции, оставляя для параметра maxsize значение по умолчанию 128:
Если для maxsize задано значение None , функция LRU отключена, и кэш может неограниченно увеличиваться.
Если для параметра typed установлено значение true, аргументы функций разных типов будут кэшироваться отдельно. Если введено false, реализация обычно будет рассматривать их как эквивалентные вызовы и кэшировать только один результат. (Некоторые типы, такие как str и int , могут кэшироваться отдельно, даже если введено false.)
Обратите внимание, что специфика типов применяется только к непосредственным аргументам функции, а не к их содержимому. Скалярные аргументы Decimal(42) и Fraction(42) обрабатываются как отдельные вызовы с разными результатами. Напротив, аргументы кортежа (‘answer’, Decimal(42)) и (‘answer’, Fraction(42)) рассматриваются как эквивалентные.
Обернутая функция оснащена функцией cache_parameters() , которая возвращает новый dict , показывающий значения для maxsize и typed . Это только для информационных целей. Изменение значений не имеет никакого эффекта.
Чтобы помочь измерить эффективность кеша и настроить параметр maxsize , обернутая функция оснащена функцией cache_info() , которая возвращает именованный кортеж , показывающий совпадения , промахи , maxsize и currsize .
Декоратор также предоставляет функцию cache_clear() для очистки или аннулирования кеша.
Исходная базовая функция доступна через атрибут __wrapped__ . Это полезно для самоанализа, для обхода кеша или для перенастройки функции другим кешем.
Кэш сохраняет ссылки на аргументы и возвращаемые значения до тех пор,пока они не выйдут из кэша или пока кэш не будет очищен.
Если метод кэшируется, аргумент экземпляра self включается в кэш. См. Как кэшировать вызовы методов?
Кэш LRU (наименее недавно использованный) работает лучше всего, когда самые последние вызовы являются лучшими предикторами предстоящих вызовов (например, самые популярные статьи на сервере новостей имеют тенденцию меняться каждый день). Ограничение размера кеша гарантирует, что кеш не будет неограниченно увеличиваться в результате длительных процессов, таких как веб-серверы.
В целом,кэш LRU следует использовать только тогда,когда вы хотите повторно использовать ранее вычисленные значения.Соответственно,не имеет смысла кэшировать функции с побочными эффектами,функции,которым необходимо создавать отдельные изменяемые объекты при каждом вызове,или нечистые функции,такие как time()или random().
Пример кэша LRU для статического веб-контента:
Пример эффективного вычисления чисел Фибоначчи с использованием кеша для реализации метода динамического программирования :
Новинка в версии 3.2.
Изменено в версии 3.3: Добавлен типизированный вариант.
Изменено в версии 3.8: Добавлена опция user_function .
Новое в версии 3.9: Добавлена функция cache_parameters()
Учитывая класс,определяющий один или более богатых методов заказа сравнения,этот класс декоратор поставляет остальные.Это упрощает работу по определению всех возможных операций богатого сравнения:
Класс должен определять одно из __lt__() , __le__() , __gt__() или __ge__() . Кроме того, класс должен предоставлять __eq__() .
В то время как этот декоратор позволяет легко создавать хорошо вели себя полностью упорядоченные типы, он действительно пришел за счет более медленного выполнения и более сложных стека следов для производных методов сравнения. Если бенчмаркинг производительности показывает, что это узкое место для данного приложения, реализация всех шести методов расширенного сравнения, скорее всего, обеспечит легкий прирост скорости.
Этот декоратор не пытается переопределить методы, объявленные в классе или его суперклассах . Это означает, что если суперкласс определяет оператор сравнения, total_ordering не будет реализовывать его снова, даже если исходный метод является абстрактным.
Новинка в версии 3.2.
Изменено в версии 3.4:Теперь поддерживается возврат NotImplemented из базовой функции сравнения для непризнанных типов.
Возвращает новый частичный объект , который при вызове будет вести себя как FUNC вызывается с позиционными аргументами арг и ключевыми аргументами ключевыми словами . Если вызову передаются дополнительные аргументы, они добавляются к args . Если предоставляются дополнительные аргументы ключевого слова, они расширяют и переопределяют ключевые слова . Примерно эквивалентно:
partial() используется для частичного применения функции, которое «замораживает» некоторую часть аргументов функции и/или ключевых слов, что приводит к созданию нового объекта с упрощенной подписью. Например, partial() можно использовать для создания вызываемого объекта, который ведет себя как функция int() , где базовый аргумент по умолчанию равен двум:
class functools.partialmethod(func, /, *args, **keywords)
Вернуть новый дескриптор partialmethod , который ведет себя как partial , за исключением того, что он предназначен для использования в качестве определения метода, а не для прямого вызова.
func должен быть дескриптором или вызываемым (объекты, которые являются обоими, как обычные функции, обрабатываются как дескрипторы).
Когда func является дескриптором (например, обычная функция Python, classmethod() , staticmethod() , abstractmethod() или другой экземпляр partialmethod ), вызовы __get__ делегируются базовому дескриптору, а в качестве результата возвращается соответствующий частичный объект .
Когда func вызывается без дескриптора, соответствующий связанный метод создается динамически. Это ведет себя как обычная функция Python при использовании в качестве метода: аргумент self будет вставлен в качестве первого позиционного аргумента, даже до аргументов и ключевых слов, предоставленных конструктору partialmethod .
Новинка в версии 3.4.
Примените функцию двух аргументов кумулятивно к элементам итерации слева направо, чтобы уменьшить итерацию до одного значения. Например, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) вычисляет ((((1+2)+3)+4)+5) . Левый аргумент x — это накопленное значение, а правый аргумент y — это обновленное значение из итеративного объекта . Если присутствует необязательный инициализатор , он помещается перед элементами итерируемого объекта в вычислении и используется по умолчанию, когда итерируемый объект пуст. Если инициализатор не указан и итерабельность содержит только один элемент, возвращается первый элемент.
См. itertools.accumulate() для итератора, который возвращает все промежуточные значения.
Чтобы определить универсальную функцию, украсьте ее декоратором @singledispatch . При определении функции с помощью @singledispatch обратите внимание, что отправка происходит по типу первого аргумента:
Чтобы добавить к функции перегруженные реализации, используйте атрибут register() универсальной функции, который можно использовать в качестве декоратора. Для функций, аннотированных типами, декоратор автоматически определит тип первого аргумента:
Для кода,который не использует аннотации типов,соответствующий аргумент типа может быть передан явно самому декоратору:
Чтобы включить регистрацию лямбда -выражений и ранее существовавших функций, атрибут register() также можно использовать в функциональной форме:
Атрибут register() возвращает функцию без декорирования. Это позволяет укладывать декораторы, pickling и создавать модульные тесты для каждого варианта независимо:
При вызове общая функция посылает тип первого аргумента:
Если нет зарегистрированной реализации для определенного типа, порядок разрешения его методов используется для поиска более общей реализации. Исходная функция, украшенная @singledispatch , зарегистрирована для базового типа object , что означает, что она используется, если не найдено лучшей реализации.
Если реализация зарегистрирована в абстрактном базовом классе , виртуальные подклассы базового класса будут отправлены в эту реализацию:
Чтобы проверить, какую реализацию универсальная функция выберет для данного типа, используйте атрибут dispatch()
Чтобы получить доступ ко всем зарегистрированным реализациям, используйте атрибут registry только для чтения :
Новинка в версии 3.4.
Изменено в версии 3.7: атрибут register() теперь поддерживает использование аннотаций типов.
Изменено в версии 3.11: атрибут register() теперь поддерживает types.UnionType и typing.Union в качестве аннотаций типов.
Чтобы определить универсальный метод, украсьте его декоратором @singledispatchmethod . При определении функции с использованием @singledispatchmethod обратите внимание, что отправка происходит по типу первого аргумента non- self или non- cls :
@singledispatchmethod поддерживает вложение с другими декораторами, такими как @classmethod . Обратите внимание, что для использования singledispatchmethod dispatcher.register быть самым внешним декоратором. Вот класс Negator с методами neg , привязанными к классу, а не экземпляр класса:
Такой же шаблон можно использовать для других похожих декораторов: @staticmethod , @abstractmethod и других.
Новинка в версии 3.8.
Обновите функцию — оболочку , чтобы она выглядела как обернутая функция. Необязательные аргументы — это кортежи, указывающие, какие атрибуты исходной функции назначаются непосредственно соответствующим атрибутам функции-оболочки и какие атрибуты функции-оболочки обновляются соответствующими атрибутами исходной функции. Значениями по умолчанию для этих аргументов являются константы уровня модуля WRAPPER_ASSIGNMENTS (которые присваивают __module__ , __name__ , __qualname__ , __annotations__ и __doc__ функции-оболочке строку документации) и WRAPPER_UPDATES (который обновляет __dict__ функции-оболочки , то есть словарь экземпляра).
Чтобы разрешить доступ к исходной функции для самоанализа и других целей (например, в обход декоратора кеширования, такого как lru_cache() ), эта функция автоматически добавляет атрибут __wrapped__ к оболочке, которая относится к оборачиваемой функции.
Основное предполагаемое использование этой функции — в функциях декоратора , которые обертывают декорированную функцию и возвращают оболочку. Если функция-оболочка не обновлена, метаданные возвращаемой функции будут отражать определение оболочки, а не исходное определение функции, что обычно менее чем полезно.
update_wrapper() может использоваться с вызываемыми объектами, отличными от функций. Любые атрибуты, указанные в назначенных или обновленных , которые отсутствуют в оборачиваемом объекте, игнорируются (т. Е. Эта функция не будет пытаться установить их в функции оболочки). AttributeError по-прежнему возникает, если в самой функции-оболочке отсутствуют какие-либо атрибуты, указанные в updated .
Новое в версии 3.2: автоматическое добавление атрибута __wrapped__ .
Новое в версии 3.2: Копирование атрибута __annotations__ по умолчанию.
Изменено в версии 3.2: Отсутствующие атрибуты больше не вызывают AttributeError .
Изменено в версии 3.4: атрибут __wrapped__ теперь всегда ссылается на обернутую функцию, даже если эта функция определяет атрибут __wrapped__ . (см. bpo-17482 )
Это удобная функция для вызова update_wrapper() в качестве декоратора функции при определении функции-оболочки. Это эквивалентно partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated) . Например:
Без использования этой фабрики декораторов имя функции примера было бы ‘wrapper’ , а строка документации исходного example() была бы потеряна.
partial Objects
partial объекты — это вызываемые объекты, созданные с помощью partial() . У них есть три атрибута только для чтения:
Вызываемый объект или функция. Вызов partial объекта будет перенаправлен на func с новыми аргументами и ключевыми словами.
Крайние левые позиционные аргументы, которые будут добавлены к позиционным аргументам, предоставленным для partial вызова объекта.
Аргументы ключевого слова, которые будут предоставлены при вызове partial объекта.
partial объекты похожи на function объекты в том смысле, что они могут быть вызваны, на них можно ссылаться слабо и они могут иметь атрибуты. Есть несколько важных отличий. Например, __name__ и __doc__ не создаются автоматически. Кроме того, partial объекты, определенные в классах, ведут себя как статические методы и не преобразуются в связанные методы во время поиска атрибутов экземпляра.