Oto samplecode wyjaśnić:Python: iterację obiektu wykonującego kodu zarówno w określonych miejscach, a także na koniec
outputText=""
counter=0
for obj in specialObjects:
if (obj.id < 400) or (obj.name.startswith("he")) or (obj.deliberateBreak==True):
print "The object %s is causing a section break."%obj.details
outputText = outputText.rjust(80)
open("file%d.txt"%counter,"w").write(outputText)
outputText=""
outputText+=obj.shortValue()
# THIS CODE IS DUPLICATED
outputText = outputText.rjust(80)
open("file%d.txt"%counter,"w").write(outputText)
Co muszę zrobić to iteracyjne nad listą tych specjalnych przedmiotów i sprawdzić kilka różne warunki za każdym razem. Jeśli którykolwiek z warunków jest spełniony (jak widać tutaj), to muszę pobrać bieżący bufor wyjściowy, zapisać go do pliku, a następnie uruchomić nowy bufor wyjściowy i kontynuować przetwarzanie.
Problem polega na powielaniu kodu. Zwróć uwagę, że dwa wiersze (outputText = i open) są duplikowane. Jeśli nie uda mi się wstawić drugiego zestawu linii, ostatni zestaw obiektów zostanie przetworzony, ale ich wynik nigdy nie zostanie zapisany.
Potrafię wymyślić dwa możliwe rozwiązania, aby zapobiec duplikacji kodu. Oba wydają się nieco nieeleganckie, więc zastanawiałem się, czy istnieje jeszcze lepszy sposób.
1) Owiń kod, który będzie powtarzany w funkcji.
outputText=""
counter=0
for obj in specialObjects:
if (obj.id < 400) or (obj.name.startswith("he")) or (obj.deliberateBreak==True):
print "The object %s is causing a section break."%obj.details
counter = writeData(outputText)
outputText=""
outputText+=obj.shortValue()
writeData(outputText,counter)
def writeData(outputText,counter):
outputText = outputText.rjust(80)
open("file%d.txt"%counter,"w").write(outputText)
return counter+1
2) Zamiast tego należy użyć pętli numerycznej i zliczać do wartości wyższej niż długość listy obiektów; stosować tę wartość jako flaga oznacza „pisać, ale teraz zamknąć”:
outputText=""
counter=0
for obj in range(len(specialObjects))+1:
if (obj = len(specialObjects)) or (specialObjects[obj].id < 400) or (specialObjects[obj].name.startswith("he")) or (specialOejcts[obj].deliberateBreak==True):
print "The object %s is causing a section break."%specialObjects[obj].details
outputText = outputText.rjust(80)
open("file%d.txt"%counter,"w").write(outputText)
outputText=""
if (obj==len(specialObjects)):
break
outputText+=specialObjects[obj].shortValue()
Gdybym miał wybrać jedną, to bym pewnie pick # 2, ale może to prowadzić do stworzenia dziwne przypadki krawędzi, przy czym Instrukcja "if", jeśli potrzebna jest jeszcze bardziej złożona logika logiczna.
Czy istnieje jeszcze bardziej czysty lub bardziej "Pythoniczny" sposób na osiągnięcie tego celu bez powielania kodu?
Dzięki!
Zmieniasz tylko "licznik" w środkowym przykładzie. Czy pierwsza i ostatnia wersja powinna otwierać wielokrotnie ten sam plik, a następnie odrzucić go bez zamykania, czy też brakuje jakiegoś kodu? – Useless
Może to być duplikat [Unikanie powtórzenia kodu po pętli?] (Http://stackoverflow.com/questions/11149997/avoiding-repeat-of-code-after-loop) – jme