Django Как реорганизовать метод дублирования

#python #django

#python #django

Вопрос:

Я использую django 2.2, и, на мой взгляд, у меня есть две функции, которые выполняют одно и то же, но изменяется только один элемент. Я хотел бы попытаться улучшить свой код, чтобы не повторять одно и то же больше раз, в основном делать то, что vm_schedule_power_on_vm делает функция, и vm_schedule_power_off_vm в одну функцию. Единственное, что изменится, это вызов vmware_poweron в vm_schedule_power_on_vm функции и vmware_poweroff в vm_schedule_power_off_vm функции.

 path('vm/schedule/<int:pk>/powered_on/', vm.vm_schedule_power_on_vm,
    name='vm_schedule_power_on_vm'),
path('vm/schedule/<int:pk>/powered_off/', vm.vm_schedule_power_off_vm,
    name='vm_schedule_power_off_vm')


def vm_schedule_power_on_vm(request, pk):
    sch = VmSchedule.objects.get(pk=pk)
    mylistvm, mylist = list(), list()
    mydate = time.strftime("%d/%m/%Y")
    for i in sch.vms.all():
        if i.lock:
            return 'locked'
        # here the order has importance because 
        # I try to have the start time and at the end the end time. 
        mylist.append(mydate)
        mylist.append(time.strftime("%H:%M:%S"))
        mylist.append(i.name)
        mylist.append(i.vmware.hostname)
        # only this line changes each time
        mylist.append(vmware_poweron(i))
        mylist.append(time.strftime("%H:%M:%S"))
        mylist.append(sch.schedule)
        mylistvm.append(mylist)
        mylist = list()
    vm_logs_export(mylistvm)
    return HttpResponse(json.dumps(mylistvm))


def vm_schedule_power_off_vm(request, pk):
    sch = VmSchedule.objects.get(pk=pk)
    mylistvm, mylist = list(), list()
    mydate = time.strftime("%d/%m/%Y")
    for i in sch.vms.all():
        if i.lock:
            return 'locked'
        mylist.append(mydate)
        mylist.append(time.strftime("%H:%M:%S"))
        mylist.append(i.name)
        mylist.append(i.vmware.hostname)
        # only this line changes each time
        mylist.append(vmware_poweroff(i))
        mylist.append(time.strftime("%H:%M:%S"))
        mylist.append(sch.schedule)
        mylistvm.append(mylist)
        mylist = list()
    vm_logs_export(mylistvm)
    return HttpResponse(json.dumps(mylistvm))

# Example result of vm_schedule_power_on_vm or vm_schedule_power_off_vm
['09/12/2021', '13:54:33', 'API1VTEST11', 'ste1vvcsa', '13:54:33', 'testPowredOn02', 
 '09/12/2021', '13:54:33', 'API1VTEST12', 'ste1vvcsa', '13:54:33', 'testPowredOn02', 
 '09/12/2021', '13:54:33', 'API1VTEST2', 'ste1vvcsa', '13:54:33', 'testPowredOn02']


def vmware_poweron(vm):
    #return list of something
    
    
def vmware_poweroff(vm):
    #return list of something
    
# Example result of vmware_poweron or vmware_poweroff
[["09/12/2021", "13:54:33", "API1VTEST11", "ste1vvcsa", "13:54:33", "testPowredOn02", 
 "09/12/2021", "13:54:33", "API1VTEST12", "ste1vvcsa", "13:54:33", "testPowredOn02", 
 "09/12/2021", "13:54:33", "API1VTEST2", "ste1vvcsa", "13:54:33", "testPowredOn02"]
 

Я думал о том, чтобы сделать в одной функции, подобной этому предыдущему коду здесь

Комментарии:

1. Почему бы не использовать одну функцию с третьим параметром «вкл.» / «выкл.», чем просто использовать if в коде, который ведет себя по-другому?

2. @Tbaki да, я заглянул в одну функцию

3. @Tbaki единственная проблема заключается в том, что условие if находится в цикле.

4. @panda42 Вам нужно использовать continue в if условии вместо return значения. Это приведет к разрыву цикла, похоже, вам нужно пропустить вместо возврата.

Ответ №1:

Самое простое, что нужно сделать, это извлечь общие операции в функцию с более общим именем, например vm_schedule_power_operation . Дайте этому третий параметр, operation , и передайте либо vmware_poweron или vmware_poweroff в качестве этого параметра.

Когда вы дойдете до строки, которая изменяется в функции, измените эту строку на вызов operation(i) вместо vmware_poweron или vmware_poweroff напрямую.

Тогда ваши on / off функции могут выглядеть следующим образом:

 def vm_schedule_power_on_vm(request, pk):
    vm_schedule_power_operation(request, pk, vmware_poweron)

def vm_schedule_power_off_vm(request, pk):
    vm_schedule_power_operation(request, pk, vmware_poweroff)
 

Комментарии:

1. Да, я думал, что некоторые так думают, но когда вы находитесь в представлении, вам нужно вернуть что-то в виде рендеринга или еще.

2. Ну, добавьте return к вызову 🙂