2013-12-12 28 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的組合。感謝您的幫助和建議。 –