2013-12-12 27 views
3

我有这个代码循环遍历一个集合,并检查集合中的某个项目是否是一个文件夹,如果是,它会检查它是哪个文件夹,然后继续执行基于它是什么文件夹。我不确定如何解释为什么有两个循环,所以我希望你们可以看看它并理解我为什么这样做,因为没有它,它就无法工作。是否有替代此代码看起来更整洁,更易于理解的代码?

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

在这种情况下,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) 

在此先感谢。

+0

您的问题的简短答案是“是的”。你可能会发现[这篇文章在Python中的“switch”](http://bytebaker.com/2008/11/03/switch-case-statement-in-python/)鼓舞人心地做得更好。 – Floris

+1

你的代码根本不使用外层循环定义的'x'变量。 –

+2

既然你说这个方法有效,你应该将其发布在[codereview](http://codereview.stackexchange.com/)上。 SO更多地处理_problems_编码,其中CR被明确设置以改善工作代码。 – iCodez

回答

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')] 
+0

谢谢,这清理了条件语句,但有没有办法使用两个for循环呢?这些是我最不喜欢的。 –

+0

@josh我只是扩展了一些有关嵌套循环的想法。 –

+0

非常感谢。 –

0

干=“不要重复自己”。当您发现自己通过复制/粘贴来编写代码时,请停下来思考自己正在做什么可以参数化,并且可以将其作为自己的函数提取出来,也可以用某种数据结构支持,或者两者兼而有之。尽管这段代码并不比编写的代码短得多,但可以更容易地跟踪循环体中发生的事情,并且添加新文件夹和关联的表单元素将会很快。 (请注意,我在这里通过使用空格来对齐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 
+0

我喜欢你的建议,并会尽量在未来继续坚持下去,但最终我选择了你的代码和Frerich的组合。感谢您的帮助和建议。 –