Как я могу предотвратить написание того же кода?Невозможно правильно написать декоратор.питон - PullRequest
0 голосов
/ 08 июня 2018

Это мой код, который работает нормально.Я использую unittest во Flask.Я не хочу повторять один и тот же код снова и снова в каждом методе.

def setUp(self):
    self.ctx = app.app_context()

def test_check_data_cleanup_functionality(self):
    with self.ctx:
        g.db_client = main_client["some_text"]
        test_json["stray"] = "abc"
        view = View.objects.get(name="test_document")
        all_fields = get_all_fields(DocumentDefinition.objects.get(name="test_document"))
        status = sanity_check(test_json, view, all_fields, old_collection=None, parent_field_id="")
        self.assertFalse(status[0]["error"])

Однако для каждого метода я не хочу вводить один и тот же код,

 with self.ctx:
        g.db_client = main_client["some_text"]

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

def timing_function(some_function):
        def wrapper(some_function_):
            with app.app_context():
                g.db_client = main_client["some_text"]
                some_function()
        return wrapper  


@timing_function
 def test_check_unique(self):
        test_json["single_line_field"] = "Hello!"
        view = View.objects.get(name="test_document")
        all_fields = get_all_fields(DocumentDefinition.objects.get(name="test_document"))
        status = sanity_check(test_json, view, all_fields, old_collection=None, parent_field_id="")
        self.assertTrue(status[0]["error"])

1 Ответ

0 голосов
/ 08 июня 2018

Это должно работать для простого декоратора:

def timing_function(func):
    def wrapper(*args, **kwargs):
        with app.app_context():
            g.db_client = main_client["ondotfreight"]
            func(*args, **kwargs)
    return wrapper

Декоратор берет func и возвращает то, что должно его заменить.Чтобы сделать его как можно более общим, внутренняя (замещающая) функция принимает *args и **kwargs, но она может быть специализированной.

Она использует глобальные переменные типа g и app, что делаетДекоратор очень зависит от среды, в которой он используется, но если ваш код без декоратора сработал, то это тоже должно быть.

Предполагая, что вы захотите добавить параметры в декоратор, например, чтобы передать ключчто входит в main_client, это будет выглядеть так:

def timing_function(main_client_name)
    def wrapper_gen(func):
        def wrapper(*args, **kwargs):
            with app.app_context():
                g.db_client = main_client[main_client_name]
                func(*args, **kwargs)
        return wrapper
    return wrapper_gen

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

@timing_function("ondotfreight")
def test_check_unique(self):
    # ... 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...