2015-12-04 120 views
0

分配變量我是比較新的規劃,我想知道如果我在一個很好的方式實現以下代碼:基於條件表達式

class Gene: 
    def __init__(self, gene_symbol, gene_id): 
     self.gene_symbol = gene_symbol 
     self.gene_id = gene_id 

     if is_valid_refseq(gene_id): 
      self.gene_id_type = REFSEQ 

     elif is_valid_ensembl_gene(gene_id): 
      self.gene_id_type = ENSEMBL_GENE 

     elif is_valid_ensembl_transcript(gene_id): 
      self.gene_id_type = ENSEMBL_TRANSCRIPT 

     else: 
      raise InvalidGeneIDError 

假設gene_idgene_id_type都是字符串。有沒有更聰明的方法來壓縮if-elif語句(特別是如果我決定添加更多這些條件的話)?我在想可能會有,但這會讓代碼變得不可讀?隨着我向前邁進,我希望開發出良好的編碼習慣/風格,並發現一些便利的工具/技巧。謝謝你的幫助!

+1

我想這大約是那樣乾淨,你可以使此代碼。 – BallpointBen

+0

如果(a)refseq,emsembl_gene和ensembl_transcript是互斥類別,或者(b)refseq是ensembl_gene的子集或特殊情況,而ensembl_gene又是ensembl_transcript的子集或特例,則此代碼有意義。如果層次結構以其他方式發揮作用,則不起作用(例如,如果所有ensembl_transcript基因也都是refseq基因)。至於風格方面,沒有什麼問題,我同意羅伯特的意見,儘可能做到可讀性。 – jez

+1

請注意,這是真正的地方要問關於嘗試但未解決的編程問題,而不是真的「是我的代碼好嗎?」輸入問題。您可能需要http://codereview.stackexchange.com/ – jez

回答

-1

您可以使用break語句添加循環。該else條款仍然如出一轍:

# somewhere outside __init__() 
checks = [is_valid_refseq, is_valid_ensembl_gene, is_valid_ensembl_transcript] 
idtypes = [REFSEQ, ENSEMBL_GENE, ENSEMBL_TRANSCRIPT] 

# in __init__() 
for check, value in zip(checks, idtypes): 
    if check(gene_id): 
     self.gene_id_type = value 
     break 
else: 
    raise InvalidGeneIDError 

你也可以用它代替兩個列表一個字典,但不能保證檢查的順序。在情況下,如果只有一個檢查可以成功地爲任何gene_id,使用字典會更好:

checks = {REFSEQ: is_valid_refreq, ENSEMBL_GENE: is_valid_ensembl_gene, 
      ENSEMBL_TRANSCRIPT: is_valid_ensembl_transcript} 
for value, check in checks.items(): 
    if check(gene_id): 
     self.gene_id_type = value 
     break 
else: 
    raise InvalidGeneIDError