可选择在类方法上使用装饰器
Posted
技术标签:
【中文标题】可选择在类方法上使用装饰器【英文标题】:Optionally use decorators on class methods 【发布时间】:2014-05-09 00:21:50 【问题描述】:我是 Python 新手,我正在为 api 构建一个包装器。我想让用户决定他/她是否想对我从模块公开的方法使用装饰器。
例如:
# create a new instance
api = MyApi()
# return a simple json response with all the data related to a timetable
print api.time_table
现在用户拥有了所有的数据,并且可以为所欲为。例如,我想添加一些“方便”的方法;让用户得到一小部分 json 而不是整个大的 json 响应。
我的想法是为此使用 python 装饰器。 (可选)我的目标应该是这样的:
# use the method and get al the data
print api.time_table
# Optionally, get a specific part, just the shows part. (PSEUDO CODE BELOW)
@shows
print api.time_table
当然,装饰器不是这样工作的,但是有没有办法在现有的类方法上选择使用装饰器,或者装饰器总是必须包装原始方法?
那么这里最 Pythonic 的方式是什么?我真的很想使用装饰器,但如果这不是一个好主意,我可以在我的 Api
类中创建更多“方便”方法。
【问题讨论】:
您只能在函数和类上使用装饰器,而不能在其他任何东西上使用装饰器(例如print
语句)。你可以扩展你的 API 来给用户更多的选择。
感谢您的快速回答,所以没有办法在现有函数上使用装饰器?在这种情况下,我不得不使用更多的类方法。使用 lambdas 可能会想出一些方便的东西。
当然你也可以使用装饰器;装饰器只是函数;应用于bar
的@foo
与bar = foo(bar)
完全相同;当以bar
作为参数调用时,将bar
替换为foo
的返回值。
【参考方案1】:
您的选择是向您的 API 添加更多方法或为用户提供实用功能:
from yourmodule import MyAPI
api = MyAPI
filtered_timetable = api.filter_on(something)
或
from yourmodule import MyAPI, filter_timetable
api = MyAPI
filtered_timetable = filter_timetable(api.time_table, something)
请记住,装饰器只是可调用的;语法:
@foo
def bar():
pass
只是语法糖:
def bar():
pass
bar = foo(bar)
foo()
被调用,返回值替换装饰对象。通常您将函数用于装饰器,但没有人说您必须仅将这些函数用作装饰器。
filter_timetable
可以是这样的装饰器;如果你有一个同时使用它的用例。
【讨论】:
以上是关于可选择在类方法上使用装饰器的主要内容,如果未能解决你的问题,请参考以下文章