Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如果条件为真,装饰函数?_Python_Python 2.7 - Fatal编程技术网

Python 如果条件为真,装饰函数?

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

我想做一些类似的事情,这(可以理解)会导致Syntaxer错误:

@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)
函数返回一个新的decorator
wrap
,然后该函数将装饰您的函数。decorator
wrap
将使用该条件来决定是否用新函数替换您的函数。

我不会为此编写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
并认为“我现在必须搜索文件的其余部分以查找分配给此函数名称的任何内容”,这是不正常的