有没有替代这个代码,看起来更整洁,更容易理解?

时间:2013-12-12 20:25:28

标签: python loops conditional

我有这个循环遍历集合的代码,并检查集合中的某个项目是否是文件夹,如果是,则检查它是哪个文件夹,然后继续执行基于操作的行为它在什么文件夹上。我不确定如何解释为什么有两个循环,所以我希望你们能看到它并理解我为什么这样做,因为没有它就行不通。

你可以看出为什么我想知道它是否可以清理......

在这种情况下,neededdirs的值是

set(['Pictures', 'Downloads', 'Public', 'Desktop'])

这是需要清理的主要代码。

neededdirs = folders.findKeyDir('active') #declares the set
for x in neededdirs: #starts the main loop
    for y in neededdirs: #starts the second loop
        if folders.getObject(neededdirs, y, 'bool'): #checks to see if the the option in the set is a folder.
            neededname = folders.getObject(neededdirs, y, 'name') #retrieves the name of the item in the set.
            if neededname == "Desktop": #this and all elif's after just check its name.
                self.folderheader1.setText(_translate("MainWindow", "Status: Active", None)) #this, the line after, and all others like it just change the text on an item if it evaluates to true.
                self.folderactive.setChecked(True)
            elif neededname == "Documents":
                self.folderheader2.setText(_translate("MainWindow", "Status: Active", None))
                self.folderactive_2.setChecked(True)
            elif neededname == "Downloads":
                self.folderheader3.setText(_translate("MainWindow", "Status: Active", None))
                self.folderactive_3.setChecked(True)
            elif neededname == "Music":
                self.folderheader4.setText(_translate("MainWindow", "Status: Active", None))
                self.folderactive_4.setChecked(True)
            elif neededname == "Pictures":
                self.folderheader1_2.setText(_translate("MainWindow", "Status: Active", None))
                self.folderactive_5.setChecked(True)
            elif neededname == "Public":
                self.folderheader1_3.setText(_translate("MainWindow", "Status: Active", None))
                self.folderactive_6.setChecked(True)
            elif neededname == "Templates":
                self.folderheader1_4.setText(_translate("MainWindow", "Status: Active", None))
                self.folderactive_7.setChecked(True)
            elif neededname == "Videos":
                self.folderheader1_5.setText(_translate("MainWindow", "Status: Active", None))
                self.folderactive_8.setChecked(True)

提前致谢。

2 个答案:

答案 0 :(得分:4)

您的所有if / elif分支仅在调用setTextsetChecked的对象上有所不同。你可以将其分解为:

knownFolders = {
    "Desktop": (self.folderheader1, self.folderactive),
    "Documents": (self.folderheader2, self.folderactive_2),
    ...
}

然后,您可以将if / elif链替换为:

if neededname in knownFolders:
    header, checkBox = knownFolders[neededname]
    header.setText(_translate("MainWindow", "Status: Active", None))
    checkBox.setChecked(True)

另外,根据代码中的注释判断,我认为你可以用一个列表理解替换两个嵌套循环,如:

relevantFolders = [folders.getObject(neededdirs, d, 'name')
                   for d in neededdirs
                   if folders.getObject(neededdirs, d, 'bool')]

答案 1 :(得分:0)

DRY =“不要重复自己”。当您发现自己通过复制/粘贴编写代码时,请停止并思考您正在做什么可以参数化,并根据自己的功能提取,或者支持某种数据结构,或两者兼而有之。虽然这段代码并不比你编写的代码短得多,但是更容易理解循环体中发生的事情,添加新文件夹和相关的表单元素将非常简单。 (请注意,我通过使用空格来对齐FolderComponent元组中的值来违反PEP-8 - 在这种情况下,我认为这是有价值的,因为它有助于突出显示您的命名方案中可能表示拼写错误或其他错误的任何变化,并将在您将来进行更改时帮助您维护它。)

from itertools import product
from collections import namedtuple

neededdirs = folders.findKeyDir('active') #declares the set

# define name->component table; using a namedtuple for these
# so you can access different tuple fields by meaningful name 
# instead of by numeric index
FolderComponent = namedtuple('FolderComponent', 'name textbox checkbox')
components = [
    FolderComponent('Desktop',   self.folderheader1, self.folderactive),
    FolderComponent('Documents', self.folderheader2, self.folderactive_2),
    FolderComponent('Downloads', self.folderheader3, self.folderactive_3),
    FolderComponent('Music',     self.folderheader4, self.folderactive_4),
    FolderComponent('Pictures',  self.folderheader5, self.folderactive_5),
    FolderComponent('Public',    self.folderheader6, self.folderactive_6),
    FolderComponent('Templates', self.folderheader7, self.folderactive_7),
    FolderComponent('Videos',    self.folderheader8, self.folderactive_8),
    ]

#start the main loop
for x,y in product(neededdirs, repeat=2):

    #check to see if the the option in the set is a folder.
    if folders.getObject(neededdirs, y, 'bool'): 

        #retrieve the name of the item in the set.
        neededname = folders.getObject(neededdirs, y, 'name')

        # set form fields
        for comp in components:
            if neededname == comp.name:
                comp.textbox.setText(_translate("MainWindow", "Status: Active", None)
                comp.checkbox.setChecked(True)
                break