Python 如果条件为真,装饰函数?
我想做一些类似的事情,这(可以理解)会导致Syntaxer错误:Python 如果条件为真,装饰函数?,python,python-2.7,Python,Python 2.7,我想做一些类似的事情,这(可以理解)会导致Syntaxer错误: @api_view(['GET']) if settings.USE_API_KEY: @authentication_classes((TokenAuthentication, )) @permission_classes((IsAuthenticated, )) def all_announcements(request): announcements = Announcement.objects.al
@api_view(['GET'])
if settings.USE_API_KEY:
@authentication_classes((TokenAuthentication, ))
@permission_classes((IsAuthenticated, ))
def all_announcements(request):
announcements = Announcement.objects.all()
serializer = AnnouncementSerializer(announcements, many=True)
return Response(serializer.data)
如何实现与此类似的功能?类似的功能:
def my_conditional_wrapper(f):
if not condition():
return f
def wrapper(*args, **kwargs):
#wrap function here
pass
return wrapper
def my_decorator(condition):
def wrap(fn):
def new_f(*args,**kwargs):
# some code that uses the function fn (fn holds a reference to the function you have decorated)
pass
if condition:
return new_f
else:
return fn
return wrap
@my_decorator(settings.USE_API_KEY)
def all_announcements(request):
...
@decorator
def f():
...
def all_announcements(request):
announcements = Announcement.objects.all()
serializer = AnnouncementSerializer(announcements, many=True)
return Response(serializer.data)
if settings.USE_API_KEY:
all_announcements = permission_classes((IsAuthenticated,))(all_announcements)
all_announcements = authentication_classes((TokenAuthentication,))(all_announcements)
all_announcements = api_view(['GET'])(all_announcements)
这样做:
def my_conditional_wrapper(f):
if not condition():
return f
def wrapper(*args, **kwargs):
#wrap function here
pass
return wrapper
def my_decorator(condition):
def wrap(fn):
def new_f(*args,**kwargs):
# some code that uses the function fn (fn holds a reference to the function you have decorated)
pass
if condition:
return new_f
else:
return fn
return wrap
@my_decorator(settings.USE_API_KEY)
def all_announcements(request):
...
@decorator
def f():
...
def all_announcements(request):
announcements = Announcement.objects.all()
serializer = AnnouncementSerializer(announcements, many=True)
return Response(serializer.data)
if settings.USE_API_KEY:
all_announcements = permission_classes((IsAuthenticated,))(all_announcements)
all_announcements = authentication_classes((TokenAuthentication,))(all_announcements)
all_announcements = api_view(['GET'])(all_announcements)
(显然,这是一个需要应用于特定代码的通用示例,您的问题中没有包括很多示例,因此我无法提供完整的示例供您复制粘贴!)
您可以将此视为
my\u decorator(condition)
函数返回一个新的decoratorwrap
,然后该函数将装饰您的函数。decoratorwrap
将使用该条件来决定是否用新函数替换您的函数。我不会为此编写decorator—请注意,decorator语法允许函数调用返回decorator(实际上,这是带参数的decorator实际做的事情)。因此:
当您使用这样的装饰器时:
def my_conditional_wrapper(f):
if not condition():
return f
def wrapper(*args, **kwargs):
#wrap function here
pass
return wrapper
def my_decorator(condition):
def wrap(fn):
def new_f(*args,**kwargs):
# some code that uses the function fn (fn holds a reference to the function you have decorated)
pass
if condition:
return new_f
else:
return fn
return wrap
@my_decorator(settings.USE_API_KEY)
def all_announcements(request):
...
@decorator
def f():
...
def all_announcements(request):
announcements = Announcement.objects.all()
serializer = AnnouncementSerializer(announcements, many=True)
return Response(serializer.data)
if settings.USE_API_KEY:
all_announcements = permission_classes((IsAuthenticated,))(all_announcements)
all_announcements = authentication_classes((TokenAuthentication,))(all_announcements)
all_announcements = api_view(['GET'])(all_announcements)
这相当于:
def f():
...
f = decorator(f)
记住这一点,你可以像这样完成你想要的:
def my_conditional_wrapper(f):
if not condition():
return f
def wrapper(*args, **kwargs):
#wrap function here
pass
return wrapper
def my_decorator(condition):
def wrap(fn):
def new_f(*args,**kwargs):
# some code that uses the function fn (fn holds a reference to the function you have decorated)
pass
if condition:
return new_f
else:
return fn
return wrap
@my_decorator(settings.USE_API_KEY)
def all_announcements(request):
...
@decorator
def f():
...
def all_announcements(request):
announcements = Announcement.objects.all()
serializer = AnnouncementSerializer(announcements, many=True)
return Response(serializer.data)
if settings.USE_API_KEY:
all_announcements = permission_classes((IsAuthenticated,))(all_announcements)
all_announcements = authentication_classes((TokenAuthentication,))(all_announcements)
all_announcements = api_view(['GET'])(all_announcements)
这个怎么样:
def timeit(method):
def timed(*args, **kw):
if 'usetimer' not in kw:
return method(*args, **kw)
elif ('usetimer' in kw and kw.get('usetimer') is None):
return method(*args, **kw)
else:
import time
ts = time.time()
result = method(*args, **kw)
te = time.time()
if 'log_time' in kw:
name = kw.get('log_name', method.__name__.upper())
kw['log_time'][name] = int((te - ts) * 1000)
else:
print '%r took %2.2f ms' % \
(method.__name__, (te - ts) * 1000)
return result
return timed
def some_func(arg1, **kwargs):
#do something here
some_func(param1, **{'usetimer': args.usetimer})
+1,我还会在
all_announcements
的顶部添加一条注释,大意是该名称不等于def
。原因是读者看到def
并认为“我现在必须搜索文件的其余部分以查找分配给此函数名称的任何内容”,这是不正常的