代码片段来自django视图代码,但没关系。
假设我有以下代码......
def unsubscribe(request):
#start of block
user = request.user
sid = request.POST.get('subscription_id')
try:
sub = Subscription.objects.get(id=sid)
except ObjectDoesNotExist:
return ajax_response(False, [('subscription', 'Given subscription does not exist.')])
if sub.user != user:
return ajax_response(False, [('subscription', 'Invalid permission.')])
#end of block.
sub.is_active = False
sub.save()
return ajax_response(True)
并且说,我有另一个函数resubscribe()
与上面的函数完全相同,除了它sub.is_active = True
。
在这种情况下,组织代码的最佳方法是什么,以便#block
和#endblock
之间的代码不重复?我想一般来说,这个问题可以写成:
有一段代码可以通过许多不同的功能进行复制和粘贴。但是,这段代码包含
return
语句。在那种情况下,抽出这条逻辑的最佳方法是什么?
编辑:固定代码段。
EDIT2:实际上,解决这个问题的简单方法是创建一个函数,比如toggle_active_status,它取request
和一个布尔值。 (我在发布问题后想出来了。)
但是,我想知道函数之间的不同逻辑超过1行的情况......比如说,#block和#endlbock之间的代码只进行输入验证,可能任意应用程序逻辑都可以来吧。
答案 0 :(得分:3)
将重复的块分解出来并传递差异,创建传递差异的包装函数:
def alter_subscription(request, make_active):
# start of block
# (...)
# end of block
sub.is_active = make_active
sub.save()
return ajax_response(True)
def unsubscribe(request):
return alter_subscription(request, False)
def resubscribe(request):
return alter_subscription(request, True)
答案 1 :(得分:1)
一种方法是简单地创建一个包含重复功能的单独函数。您可以使用函数的参数来引入必要的差异。
如果代码片段返回了某些内容,那么您可以使用约定,例如,如果函数不应返回则返回None
,否则返回对象。在调用函数中,只测试返回的参数是否为None
,如果不是None
则返回返回的变量。
答案 2 :(得分:1)
尚未显示的几个选项:
由于这是一个验证例程,因此使用例外来表示失败,并使用正常的None(忽略)返回来表示成功:
def verify_permissions(request):
user = request.user
sid = request.POST.get('subscription_id')
try:
sub = Subscription.objects.get(id=sid)
except ObjectDoesNotExist:
raise PermissionError, 'Given subscription does not exist.'
if sub.user != user:
raise PermissionError, 'Invalid permission.'
def subscribe(request):
try:
verify_permissions(request)
sub.save()
return ajax_response(True)
except PermissionError, why:
return ajax_response(False, [('subscription', why)])
或者,因为Python是动态类型的,并且以两种不同的方式调用ajax_response
显然是可以的:返回用于构造响应的参数,并检查第一个的值。
def verify_permissions(request, purpose):
user = request.user
sid = request.POST.get('subscription_id')
try:
sub = Subscription.objects.get(id=sid)
except ObjectDoesNotExist:
return (False, [(purpose, 'Given subscription does not exist.')])
if sub.user != user:
return (False, [(purpose, 'Invalid permission.')])
return (True,)
def subscribe(request):
result = verify_permissions(request, 'subscription')
if result[0]: sub.save()
return ajax_response(*result)