Каково некоторое общее использование для декораторов Python? [закрытый]

Ссылка на документ здесь: https://apidock.com/rails/v3.2.8/ActionView/Helpers/FormOptionsHelper/options_for_select

options_for_select({ "Basic" => "$20", "Plus" => "$40" }, "$40")
  \n

Предположим, в вашем файле локали названия языков следующие:

en:
  languages:
    en: 'English'
    de: 'German'
    ga: 'Irish'
    fr: 'French'

Я думаю, что вам нужно что-то вроде следующего:

f.select :language, options_for_select(
  LanguageName::LANGUAGES.map { |lang| [t("languages.#{lang}"), lang] }.to_h
  f.object.language || t('languages.fr')
)

Конечно, всегда лучше извлечь метод из в вспомогательный файл:

class ApplicationHelper
  def map_locale_names(locale)
    LanguageName::LANGUAGES.map { |lang| [t("languages.#{lang}", locale: locale), lang] }.to_h
  end
end

, чтобы ваш метод стал следующим:

f.select :language, options_for_select(
  map_locale_names(locale: params[:locale]),
  f.object.language || t('languages.fr')
)

Надеюсь, это поможет.

328
задан tshepang 6 July 2014 в 23:32
поделиться

10 ответов

Я использую декораторов главным образом для синхронизации целей

def time_dec(func):

  def wrapper(*arg):
      t = time.clock()
      res = func(*arg)
      print func.func_name, time.clock()-t
      return res

  return wrapper


@time_dec
def myFunction(n):
    ...
123
ответ дан RSabet 23 November 2019 в 00:48
поделиться

Я использовал их для синхронизации.

import functools

def synchronized(lock):
    """ Synchronization decorator """
    def wrap(f):
        @functools.wraps(f)
        def newFunction(*args, **kw):
            lock.acquire()
            try:
                return f(*args, **kw)
            finally:
                lock.release()
        return newFunction
    return wrap

, Как указано в комментариях, начиная с Python 2.5 можно использовать with оператор в сочетании с threading.Lock (или multiprocessing.Lock начиная с версии 2.6) объект упростить реализацию декоратора до просто:

import functools

def synchronized(lock):
    """ Synchronization decorator """
    def wrap(f):
        @functools.wraps(f)
        def newFunction(*args, **kw):
            with lock:
                return f(*args, **kw)
        return newFunction
    return wrap

Невнимательный, Вы затем используете его как это:

import threading
lock = threading.Lock()

@synchronized(lock)
def do_something():
  # etc

@synchronzied(lock)
def do_something_else():
  # etc

В основном это просто помещает lock.acquire() / lock.release() по обе стороны от вызова функции.

95
ответ дан Aran-Fey 23 November 2019 в 00:48
поделиться

Декораторы используются для чего-либо, что Вы хотите прозрачно "перенести" с дополнительной функциональностью.

Django использует их для обертывания "вход в систему, требуемый" функциональность выставленные для обозрения функции , а также для регистрирующие функции фильтра .

можно использовать декораторов класса для добавление, названное журналами к классам .

Любая достаточно универсальная функциональность, которую можно "прикрепить на" к существующему классу, или поведение функции является справедливой игрой для художественного оформления.

существует также обсуждение вариантов использования на группе новостей Python-Dev указаны PEP 318 - Декораторы для Функций и Методов .

47
ответ дан Community 23 November 2019 в 00:48
поделиться

Для nosetests можно записать декоратору, который предоставляет функцию модульного теста или метод с несколькими наборами параметров:

@parameters(
   (2, 4, 6),
   (5, 6, 11),
)
def test_add(a, b, expected):
    assert a + b == expected
24
ответ дан Torsten Marek 23 November 2019 в 00:48
поделиться

Я использую их главным образом для отладки (обертка вокруг функции, которая печатает ее аргументы и результат) и проверка (например, проверять, имеет ли аргумент корректный тип или, в случае веб-приложения, если у пользователя есть необходимые полномочия для вызова конкретного метода).

8
ответ дан DzinX 23 November 2019 в 00:48
поделиться

Я недавно использовал их при работе над веб-приложением социальной сети. Для Сообщества/Групп я, как предполагалось, дал авторизацию членства создать новое обсуждение и ответ на сообщение, необходимо быть членом той конкретной группы. Так, я записал декоратору @membership_required и поместил это, где я потребовал, по моему мнению.

5
ответ дан tshepang 23 November 2019 в 00:48
поделиться

Я использую декораторов для параметров проверки типа, которые передаются моим методам Python через некоторый RMI. Таким образом вместо того, чтобы повторить тот же подсчет параметра, повышающий исключение фетиш снова и снова

def myMethod(ID, name):
    if not (myIsType(ID, 'uint') and myIsType(name, 'utf8string')):
        raise BlaBlaException() ...

Я просто объявляю

@accepts(uint, utf8string)
def myMethod(ID, name):
    ...

и принимает (), делает всю работу для меня.

67
ответ дан Evgeni Sergeev 23 November 2019 в 00:48
поделиться

Библиотека Twisted использует декораторов, объединенных с генераторами для предоставления иллюзии, что асинхронная функция синхронна. Например:

@inlineCallbacks
def asyncf():
    doStuff()
    yield someAsynchronousCall()
    doStuff()
    yield someAsynchronousCall()
    doStuff()

Используя это, код, который был бы разбит в тонну небольших функций обратного вызова, может быть написан вполне естественно как единственный блок, делая намного легче понять и поддержать.

23
ответ дан DNS 23 November 2019 в 00:48
поделиться

Декораторы используются или для определения свойств функции или как шаблон, который изменяет его; это возможно, но парадоксально для них для возврата совершенно других функций. Смотря на другие ответы здесь, кажется, что один из наиболее популярных способов использования должен ограничить объем некоторого другого процесса - быть этим вход, профилирование, проверки безопасности, и т.д.

CherryPy использует диспетчеризацию объекта для соответствия URL к объектам и, в конечном счете, методы. Декораторы на тех методах предупреждают, разрешают ли CherryPy даже использовать те методы. Например, адаптированный из учебного руководства:

class HelloWorld:

    ...

    def secret(self):
        return "You shouldn't be here."

    @cherrypy.expose
    def index(self):
        return "Hello world!"

cherrypy.quickstart(HelloWorld())
5
ответ дан Nikhil Chelliah 23 November 2019 в 00:48
поделиться

Я использую следующий декоратор для создания потоковой безопасности функции. Это делает код более читабельным. Он почти аналогичен предложенному Джоном Фухи, но разница в том, что один работает с одной функцией и нет необходимости явно создавать объект блокировки.

def threadsafe_function(fn):
    """decorator making sure that the decorated function is thread safe"""
    lock = threading.Lock()
    def new(*args, **kwargs):
        lock.acquire()
        try:
            r = fn(*args, **kwargs)
        except Exception as e:
            raise e
        finally:
            lock.release()
        return r
    return new

class X:
    var = 0

    @threadsafe_function     
    def inc_var(self):
        X.var += 1    
        return X.var
6
ответ дан 23 November 2019 в 00:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: