Nano Hash - криптовалюты, майнинг, программирование

Передать метод декоратору с аргументами?

Можно ли передать декорированный метод с аргументами __init__ декоратора?

Простой декоратор и пример использования

class Decorator(object):
    def __init__(self, *args):
        print args

    def __call__(self, func): # yep the method still have to be callable
        return func

@Decorator
def foo():
    pass

Декоратор без аргументов передаст метод в качестве аргумента

$ python foo.py
(<function foo at 0x7fefd7ac1b90>,)

Когда я добавляю аргументы в декоратор

@Decorator(1, 2, 3)
def foo():
    pass

это приводит к

$ python test.py 
(1, 2, 3)

Как видите, метод теперь отсутствует в переданных аргументах.


  • Попробуйте пример с @Decorator() и, возможно, он будет щелкать. 28.03.2014
  • здесь есть отличное описание (на мой взгляд, один из лучших ответов в стеке) 28.03.2014
  • @Decorator в основном означает foo = Decorator(foo). Поэтому @Decorator(1, 2, 3) означает foo = Decorator(1, 2, 3)(foo); Decorator(1, 2, 3) должен вернуть декоратор. 28.03.2014

Ответы:


1

Когда мы передаем аргументы декоратору, нам нужно создать дополнительную функцию, которая принимает эти аргументы, а затем возвращает фактический декоратор:

def decorator_creator(*args):
    class Decorator(object):
        def __init__(self, func):
            print args
            print func
            self.func = func
        def __call__(self):
            return self.func()
    return Decorator

@decorator_creator(1, 2, 3)
def foo():
    pass

Выход:

(1, 2, 3)
<function foo at 0x0000000002EB9EB8>
27.03.2014
  • Вероятно, стоит отметить, что в подавляющем большинстве случаев реализация декоратора в виде класса, даже если ему нужны аргументы, является излишним и, возможно, менее понятным кодом; обычно достаточно внешнего замыкания, и код становится более читаемым. Или, по крайней мере, определите объект декоратора за пределами области действия функции декоратора, а затем инициализируйте и верните экземпляр при вызове декоратора. 28.03.2014
  • Просто небольшое замечание: не будет ли этот код создавать класс Decorator каждый раз, когда применяется декоратор? 28.03.2014
  • @PauloBu Это необходимо, потому что здесь мы используем свободную переменную args в нашем классе. Если мы переместим класс за пределы функции, то класс не сможет получить доступ к args. 28.03.2014
  • Если вы не сделаете args аргументы для класса __init__ и не вернете экземпляр, что здесь имеет больше смысла... 28.03.2014
  • @ Lucas Я случайно удалил метод __call__ вместо того, чтобы исправить его. 28.03.2014
  • @SilasRay Если я верну экземпляр из decorator_creator, он вызовет метод __call__ этого экземпляра во время самого создания функции. 28.03.2014

  • 2

    Альтернатива, которой не нужны внутренние классы:

    class decorator(object):
        def __init__(self, *args):
            # This creates the decorator
            self.args = args
    
        def __call__(self, func):
            # This applies the decorator
            self.func = func
            return self.call
    
        def call(self, *moreargs):
            # And this happens when the original function is called
            print self.args, self.func, moreargs
            return self.func()
    
    @decorator(1, 2, 3)
    def foo():
        pass
    

    Я также использовал functools.partial(self.method, func) для декораторов. Иногда полезно.

    28.03.2014
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..