Когда вы пишете
@MyProperty(int)
def myFunction(foo)
...
, это означает, что вызывается MyProperty(int)
, и все, что возвращается, затем вызывается с myFunction
в качестве аргумента. Поэтому MyProperty
должна быть функцией, которая возвращает функцию, которая принимает функцию и возвращает функцию.
Таким образом, вы можете написать свой декоратор примерно так:
def MyProperty(optional=None):
def decorator(func):
def getter(*args, **kwargs):
"""unspecified magic goes here"""
return func(*args, **kwargs) if not optional else optional(func(*args, **kwargs))
return getter
return decorator
Итак MyProperty(int)
возвращает функцию (decorator
), а decorator
возвращает все, что вы украшаете.
Однако, когда вы вызываете ее без аргумента, вам все равно нужно вызвать ее @MyProperty()
вместо @MyProperty
, иначе вы пропустите этап распаковки.
>>> class MyClass:
... @MyProperty()
... def f1(foo):
... return foo
... @MyProperty(int)
... def f2(foo):
... return foo
...
>>> MyClass.f1(1.5)
1.5
>>> MyClass.f2(1.5)
1
Я не уверен насчет вашего использования property
. Обе ваши функции в этом примере являются просто функциями внутри класса. У них нет аргумента self
или cls
, и вы вызываете их из самого класса, а не из экземпляра. Несколько неясно, к чему вы стремились.
Когда я попробовал это в Python 2, мне пришлось объявить функции как статические методы, чтобы это работало.
>>> class MyClass(object):
... @staticmethod
... @MyProperty()
... def f1(foo):
... return foo
... @staticmethod
... @MyProperty(int)
... def f2(foo):
... return foo
...
>>> MyClass.f1(0.5)
0.5
>>> MyClass.f2(1.5)
1