В строке меню: Проект -> Свойства -> Компилятор 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 находится на пути построения проекта, сохраните все и наслаждайтесь!
При использовании декоратора Вы заменяете одну функцию другим. Другими словами, если у Вас есть декоратор
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'
Я очень часто использую классы, а не функции для своих декораторов. У меня были некоторые проблемы с этим, потому что объект не будет иметь всех тех атрибутов, которые ожидаются от функции. Например, у объекта не будет атрибута __ 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)