属性 带可选参数的装饰器
Property decorator with optional argument
我想创建一个 class 属性 带有接受可选参数的装饰器。通常我会写
def MyProperty(func, optional=None):
def getter():
"""magic goes here"""
return func() if not optional else optional(func())
return property(getter)
class MyClass(object):
@MyProperty
def myFunction(foo):
return foo
MyClass().myFunction(5.)
>>> 5.0
这一切都很好,但是当我现在也像这样沿着装饰器传递一个函数时:
class MyClass(object):
@MyProperty(int)
def myFunction(foo):
return foo
我现在打电话给
MyClass().myFunction(5)
>>> TypeError: 'property' object is not callable
虽然我希望得到 int(5)
作为结果。
写的时候
@MyProperty(int)
def myFunction(foo)
...
这意味着 MyProperty(int)
被调用,然后 returns 以 myFunction
作为参数被调用。所以MyProperty
应该是一个函数,returns一个接受函数的函数,returns一个函数。
所以你可以这样写你的装饰器:
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)
returns一个函数(decorator
),decorator
returns不管你在装饰什么。
然而,当你在没有参数的情况下调用它时,你仍然需要调用它 @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
的使用。示例中的两个函数都只是 class 中的函数。它们没有 self
参数或 cls
参数,您是从 class 本身调用它们,而不是从实例调用它们。有点不清楚你的目标是什么。
当我在 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
我想创建一个 class 属性 带有接受可选参数的装饰器。通常我会写
def MyProperty(func, optional=None):
def getter():
"""magic goes here"""
return func() if not optional else optional(func())
return property(getter)
class MyClass(object):
@MyProperty
def myFunction(foo):
return foo
MyClass().myFunction(5.)
>>> 5.0
这一切都很好,但是当我现在也像这样沿着装饰器传递一个函数时:
class MyClass(object):
@MyProperty(int)
def myFunction(foo):
return foo
我现在打电话给
MyClass().myFunction(5)
>>> TypeError: 'property' object is not callable
虽然我希望得到 int(5)
作为结果。
写的时候
@MyProperty(int)
def myFunction(foo)
...
这意味着 MyProperty(int)
被调用,然后 returns 以 myFunction
作为参数被调用。所以MyProperty
应该是一个函数,returns一个接受函数的函数,returns一个函数。
所以你可以这样写你的装饰器:
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)
returns一个函数(decorator
),decorator
returns不管你在装饰什么。
然而,当你在没有参数的情况下调用它时,你仍然需要调用它 @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
的使用。示例中的两个函数都只是 class 中的函数。它们没有 self
参数或 cls
参数,您是从 class 本身调用它们,而不是从实例调用它们。有点不清楚你的目标是什么。
当我在 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