2017-08-10 120 views
1

我仍然在學習的Python(3.5),我有這段代碼它需要很多的值賦給一些對象,所以我想知道什麼是最優化的方式做它。我這樣問是因爲我缺乏瞭解循環中「少量代碼」是否比不使用循環要求更高的時間要求(文件大小較小,但是處理速度增加了......也許會?),因此缺乏這方面的知識。 。減少代碼行,而不會影響性能

方法1:

# 01 
    self.lineReferencia1.setText(utilidades.ensure_its_str(registro[16])) 
    self.lineConcepto1.setText(utilidades.ensure_its_str(registro[17])) 
    self.lineCantidad1.setText(utilidades.ensure_its_str(registro[18])) 
    self.linePrecio1.setText(utilidades.ensure_its_str(registro[19])) 
    self.lineDescuento1.setText(utilidades.ensure_its_str(registro[20])) 
    # 02 
    self.lineReferencia2.setText(utilidades.ensure_its_str(registro[23])) 
    self.lineConcepto2.setText(utilidades.ensure_its_str(registro[24])) 
    self.lineCantidad2.setText(utilidades.ensure_its_str(registro[25])) 
    self.linePrecio2.setText(utilidades.ensure_its_str(registro[26])) 
    self.lineDescuento2.setText(utilidades.ensure_its_str(registro[27])) 
    # 03 
    self.lineReferencia3.setText(utilidades.ensure_its_str(registro[30])) 
    self.lineConcepto3.setText(utilidades.ensure_its_str(registro[31])) 
    self.lineCantidad3.setText(utilidades.ensure_its_str(registro[32])) 
    self.linePrecio3.setText(utilidades.ensure_its_str(registro[33])) 
    self.lineDescuento3.setText(utilidades.ensure_its_str(registro[34])) 
    # 04 
    self.lineReferencia4.setText(utilidades.ensure_its_str(registro[37])) 
    self.lineConcepto4.setText(utilidades.ensure_its_str(registro[38])) 
    self.lineCantidad4.setText(utilidades.ensure_its_str(registro[39])) 
    self.linePrecio4.setText(utilidades.ensure_its_str(registro[40])) 
    self.lineDescuento4.setText(utilidades.ensure_its_str(registro[41])) 

方法2:

items = (
    (self.lineReferencia1, registro[16]), (self.lineConcepto1, registro[17]), (self.lineCantidad1, registro[18]), 
    (self.linePrecio1, registro[19]), (self.lineDescuento1, registro[20]), (self.lineReferencia2, registro[23]), 
    (self.lineConcepto2, registro[24]), (self.lineCantidad2, registro[25]), (self.linePrecio2, registro[26]), 
    (self.lineDescuento2, registro[27]), (self.lineReferencia3, registro[30]), (self.lineConcepto3, registro[31]), 
    (self.lineCantidad3, registro[32]), (self.linePrecio3, registro[33]), (self.lineDescuento3, registro[34]), 
    (self.lineReferencia4, registro[37]), (self.lineConcepto4, registro[38]), (self.lineCantidad4, registro[39]), 
    (self.linePrecio4, registro[40]), (self.lineDescuento4, registro[41])) 
    for i in items: 
     i[0].setText(utilidades.ensure_its_str(i[1])) 

注:採用這種方法,我減少20行代碼到只有10,但真正的代碼不只有4個部分,它有27個,所以目標是減少135行代碼。

方法3:

會使用字典來存儲,而不是一個元組的元組數據,會更有效的proccesing的時間?

方法4:

我應該使用方法/函數對每個項目,而不是一個循環?

真正的問題:有沒有其他方法可以減少該文件上的代碼行而不會影響性能或可讀性?怎麼樣?爲什麼?

+1

我的直接反應是:爲什麼要有'variableName1','variableName2'等?把它們加在一個數據結構中,'variableName = [...]',這樣你就可以迭代它們。我強烈建議不採用方法2,因爲代碼變得非常模糊。 – pingul

+0

可以說,如果你是唯一一個要維護這段代碼的人,你幾乎可以做任何你想做的事情。但是,如果其他人將來不得不保持/改變它,那麼編碼時最好是明確的,即使這是重複的。這就是cut'n'paste和編輯們的目的。 –

+1

具有相同名稱的變量與結尾數字不同的是代碼異味('linePrecio1','linePrecio2','linePrecio3','linePrecio4')。對於這些東西,最好使用類似列表或字典或對象的東西。 –

回答

7

代碼本身看起來像厲害開發接口,但假設你必須使用它,你可以通過編程獲取對象的屬性與getattr

因此,組ID,索引的參考點和屬性,讓水木清華像

groups = (1, 2, 3, 4) 
attrs = ('Referencia', 'Concepto', 'Cantidad', 'Precio', 'Descuento') 
idx = (15, 22, 29, 38) 

for group, index in zip(groups, idx): 
    for i, attr in enumerate(attrs): 
     getattr(self, 'line' + attr + str(i)).setText(utilidades.ensure_its_str(registro[i+index])) 

關於整體代碼質量:

  • 這樣命名(連續名稱)是非常糟糕的設計。如果你有序列 - 你可能需要將這些數據存儲在序列 - 商店lineReferencia爲對象的名單
  • 你可以來到這個在某些時候,或者你可能沒有,但要儘量保持你的代碼英文名 - 這使它對於廣泛的人羣更具可讀性。有時它可能成爲代碼庫支持
+0

是的,我忘了說我無法控制GUI或項目生成的方式,但我必須爲它們賦值。我想創建一個已經創建的Qt GUI的邏輯。 – Saelyth

+0

生活是艱難的:)儘可能地從這個經驗中學習 – Slam

+0

這是一個體面的方法,但是如果表單元素的名稱被改變,它自然會中斷。另外,做getattr'跳舞只需要一次就可以是一個好主意,比如說一個表單元素的列表。 – AKX

0

好點的方法是至關重要的:面向對象

是應創建領域Referncia,Concepto線對象......和你的主類包含行的列表。這將與您的擴展版本一樣快。

Class Line: 
    def __init__(self, ......): 
     self.referencia = ..... 

Class Polygon: 
    def __init__(self): 
     self.lines =() 
     line1 = Line(.......) 
     self.lines.append(line1) 
     line2 = 

的快捷方式:對於解釋語言

member_names = ("lineReferencia", "lineConcepto", "lineCantidad", "linePrecio", "lineDescuento") 
for i in range(4): 
    for member_name in member_names: 
     text_widdget = self.__dict__["lineReferencia" + str(i)] 
     i_register = 16 + member_names.index(member_name) + 7 * i 
     text_widget.setText(utilidades.ensure_its_str(registro[i_register])) 

注意使用self.__dict__這是一個包含當前對象的成員變量與自己的名字作爲鍵的字典。