Определить параметр декоратора вне области модуля - PullRequest
1 голос
/ 18 июня 2020

У меня следующий декоратор работает нормально с параметром

from functools import wraps

def sumproduct(cnt):
    def dec(f):
        @wraps(f)
        def wrap(*args):
            print('inside wrapper')
            _sum = 0
            for i in range(cnt):
                _sum = _sum + sum([i * a for a in args])
            f(_sum)
        return wrap
    return dec

cnt = 3
@sumproduct(cnt)
def myfunc(num):
    print(num)

if __name__ == "__main__":
    myfunc(10)

Результат - 30, что составляет 0*10 + 1*10+ 2*10

Однако я хотел бы импортировать этот модуль в другое место , например, в тестовый модуль. Я хотел бы сделать что-то вроде следующего, чтобы cnt не определялся в глобальной области:

from functools import wraps

def sumproduct(cnt):
    def dec(f):
        @wraps(f)
        def wrap(*args):
            print('inside wrapper')
            _sum = 0
            for i in range(cnt):
                _sum = _sum + sum([i * a for a in args])
            f(_sum)
        return wrap
    return dec

@sumproduct(cnt)
def myfunc(num):
    print(num)

if __name__ == "__main__":
    cnt = 3
    myfunc(10)

Как я могу определить cnt, чтобы

  1. cnt всегда 3 при выполнении кода?
  2. и cnt не импортируются при импорте модуля?

Примечание: Это просто примерное представление кода. Предположим, что cnt - это соединение с базой данных, которое подключается к производственной базе данных. Я хотел бы использовать другое соединение с базой данных для тестов, поэтому я не хочу импортировать соединение с производственной базой данных в тестовый модуль.

1 Ответ

2 голосов
/ 18 июня 2020

Вы можете использовать @sumproduct(lambda: cnt). Таким образом, выполнение откладывается.

Например:

from functools import wraps

def sumproduct(cnt):
    def dec(f):
        @wraps(f)
        def wrap(*args):
            print('inside wrapper')
            _sum = 0
            for i in range(cnt()):  # <---- Note the ()
                _sum = _sum + sum([i * a for a in args])
            f(_sum)
        return wrap
    return dec


@sumproduct(lambda: cnt) # <--- put lambda: here
def myfunc(num):
    print(num)

if __name__ == "__main__":
    cnt = 3
    myfunc(10)

Выводит:

inside wrapper
30
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...