Что делает functools.wraps?

В строке меню: Проект -> Свойства -> Компилятор Java

Включить специальные настройки проекта (отмечен) Снимите флажок «Использовать соответствие из среды исполнения» .... Выберите желаемый «уровень соответствия компилятора»

Это позволит вам скомпилировать код «1.5» с помощью JDK «1.6».

Если вы хотите использовать 1,5 JDK для создания «1,5-дюймового» кода, тогда установите подходящий 1,5 JDK и скажем затмение, где он установлен через:

Окно -> настройки -> Установленные JREs

Затем вернитесь к проекту

Project -> свойства -> Java Build Path -> libraries

удалить языковые версии 1.6 и: добавить библиотеку ... -> JRE System LIbrary -> Alternate JRE -> JRE, который вы хотите.

Убедитесь, что правильная JRE находится на пути построения проекта, сохраните все и наслаждайтесь!

545
задан Machavity 17 April 2019 в 21:50
поделиться

2 ответа

При использовании декоратора Вы заменяете одну функцию другим. Другими словами, если у Вас есть декоратор

def logged(func):
    def with_logging(*args, **kwargs):
        print(func.__name__ + " was called")
        return func(*args, **kwargs)
    return with_logging

тогда, когда Вы говорите

@logged
def f(x):
   """does some math"""
   return x + x * x

, это - точно то же, что

def f(x):
    """does some math"""
    return x + x * x
f = logged(f)

и Ваша функция f заменяется функцией with_logging. К сожалению, это означает, что, если Вы тогда говорите

print(f.__name__)

, это распечатает with_logging, потому что это - название Вашей новой функции. На самом деле при рассмотрении docstring для f это будет пробел, потому что with_logging не имеет никакого docstring, и таким образом, docstring, который Вы записали, не будет там больше. Кроме того, при рассмотрении результата pydoc для той функции он не будет перечислен как взятие одного аргумента x; вместо этого это будет перечислено как взятие *args и **kwargs, потому что это - то, что берет with_logging.

При использовании декоратора всегда означал терять эту информацию о функции, это будет серьезная проблема. Вот почему мы имеем functools.wraps. Это берет функцию, используемую в декораторе, и добавляет функциональность копирования по имени функции, docstring, списку аргументов, и т.д. И так как wraps самостоятельно декоратор, следующий код делает корректную вещь:

from functools import wraps
def logged(func):
    @wraps(func)
    def with_logging(*args, **kwargs):
        print(func.__name__ + " was called")
        return func(*args, **kwargs)
    return with_logging

@logged
def f(x):
   """does some math"""
   return x + x * x

print(f.__name__)  # prints 'f'
print(f.__doc__)   # prints 'does some math'
923
ответ дан Prince Odame 17 April 2019 в 21:50
поделиться

Я очень часто использую классы, а не функции для своих декораторов. У меня были некоторые проблемы с этим, потому что объект не будет иметь всех тех атрибутов, которые ожидаются от функции. Например, у объекта не будет атрибута __ name __ . У меня была конкретная проблема с этим, которую было довольно сложно отследить, где Django сообщал об ошибке «объект не имеет атрибута ' __ name __ '». К сожалению, для декораторов в стиле классов я не верю, что @wrap справится со своей задачей. Вместо этого я создал такой базовый класс декоратора:

class DecBase(object):
    func = None

    def __init__(self, func):
        self.__func = func

    def __getattribute__(self, name):
        if name == "func":
            return super(DecBase, self).__getattribute__(name)

        return self.func.__getattribute__(name)

    def __setattr__(self, name, value):
        if name == "func":
            return super(DecBase, self).__setattr__(name, value)

        return self.func.__setattr__(name, value)

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

class process_login(DecBase):
    def __call__(self, *args):
        if len(args) != 2:
            raise Exception("You can only specify two arguments")

        return self.func(*args)
21
ответ дан 22 November 2019 в 22:07
поделиться
Другие вопросы по тегам:

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