简体   繁体   English

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

[英]Is there an alternative to this code that looks neater and is more comprehensible?

I have this code which loops through a set, and checks to see if one of the items in the set is a folder, and if it is, it checks to see which folder it is and then proceeds to perform an action based on what folder it is. 我有这个代码循环一个集合,并检查集合中的一个项目是否是一个文件夹,如果是,它检查它是什么文件夹,然后继续执行基于什么文件夹的操作它是。 I'm not really sure how to explain why there are two loops, so I'm hoping you guys can look at it and understand why I did that, because it doesn't work without it. 我不太确定如何解释为什么有两个循环,所以我希望你们能看到它并理解我为什么这样做,因为没有它就行不通。

You can see why I'm wondering if it can be cleaned up... 你可以看出为什么我想知道它是否可以清理......

In this case, the value of neededdirs is 在这种情况下,requireddirs的值是

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

and here's the main code which needs to be cleaned up. 这是需要清理的主要代码。

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)

Thanks in advance. 提前致谢。

All your if / elif branches differ only in the object on which setText and setChecked is called. 所有if / elif分支仅在调用setTextsetChecked的对象上有所不同。 You could factor that out into something like: 您可以将其分解为:

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

You could then replace your if / elif chain with: 然后,您可以用以下内容替换if / elif链:

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

Also, judging by the comments in the code, I think you could replace the two nested loops with a single list comprehension like: 另外,根据代码中的注释判断,我认为你可以用一个列表理解来替换两个嵌套循环,如:

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

DRY = "Don't Repeat Yourself". DRY =“不要重复自己”。 When you find yourself writing code by copy/paste, stop and think how what you are doing could be parameterized, and either extracted out as a function of its own, or supported with some kind of data structure, or both. 当您发现自己通过复制/粘贴编写代码时,请停止并思考您正在做什么可以参数化,并根据自己的功能提取,或者支持某种数据结构,或两者兼而有之。 While this code isn't much shorter than what you wrote, it is easier to follow what is happening in the body of the loop, and adding new folders and associated form elements will be a snap. 虽然这段代码并不比你编写的代码短得多,但是更容易理解循环体中发生的事情,添加新文件夹和相关的表单元素将非常简单。 (Note that I violated PEP-8 here by using spaces to align the values in the FolderComponent tuples - in this case, I think it is of merit, as it helps highlight any variations from your naming scheme that might indicate a typo or other bug, and will help you maintain it as you make changes in the future.) (请注意,我通过使用空格来对齐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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM