我有一個包含基因排序的「基因型」。這些基因代表的並不重要,它們只是任意可以被稱爲「基因對象」的任意對象。如何符合人體工程學的迭代函數與不同的簽名
我需要這種突變基因,通過多種方法,但函數簽名不是全部匹配。給定一個起始基因,創建一個新的基因,隨機選擇這些方法之一(或沒有方法)進行突變。
例如,我有duplicate(gene)
,replace(gene, othergene)
,insert(gene, othergene)
,delete(gene)
,和othermutation(gene, genotype)
。所有這些都會返回一個基因列表(即使該列表只包含一個元素或零個元素),以便保持函數簽名之間的同質性。
我想這種情況推廣到這些突變的功能列表及相關百分比機會使用。我已經通過二進制搜索和累積分佈選擇這些基因的方法,我產生一個R和可基於來自R.舍入二進制索引檢索正確的功能,這大致可以讓我做到以下幾點:
def mutate(genotype, mutation_list, cumulative_probabilities)
mutated_genotype = []
for gene in genotype:
r = random.random()
mutation = mutation_list(cumulative_probabilities(r))
mutated_genotype.extend(mutation(gene))
return mutated_genotype
理想情況下,我不需要知道第五行的突變,我只需要在相關概率的某個位置有一個突變列表。正如你所看到的,replace(gene, othergene)
需要第二個參數會發生什麼?或othermutation(gene, genotype)
需要一個不同但也是單獨的參數?
爲了解決這個問題,我已經到了多種解決方案。首先,我可以吸收所有功能簽名完全相同。我的意思是,即使duplicate(gene)
不需要othergene
我仍然會把它放在函數定義中,它只是不會使用它,或者它會做一些微不足道的事情。但是這個解決方案的缺點是每次我需要添加一個帶有新參數的新函數時,我需要更改所有的函數簽名,這違反了SRP類,對於所有函數來說都是這樣,並且會煩人地處理。但是我可以把它作爲一個參數對象來包裝,我在每次迭代中設置需要的參數。如果需要帶有新類型參數的新函數,我可以簡單地將該參數添加到「突變參數」對象中,並將該對象傳遞給每個函數,並且每個函數只會獲得它所需的內容,例如:
for gene in genotype:
#note other gene is created from some other function or is a generator itself
mutation_parameter = MutationParameter(gene, genotype, othergene)
r = random.random()
mutation = mutation_list(cumulative_probabilities(r))
mutated_genotype.extend(mutation(mutation_parameter))
這裏的堅持己見的是,MutationParameter
成員不一定所有的彼此相關,我們必須知道什麼突變簽名的手之前,你將不只是能夠添加新的簽名,需要更新代碼的多個部分。
我可以處理這個問題的另一種方法是我可以使函數參數具有通用性,但是通過這種方式,我將被迫添加額外的數據結構來處理將數據拉入函數簽名(所以所有函數都採用*args
或**kwargs
),並且這可能意味着每個簽名的定製函數,並且由於需要將累積概率線性化或關聯到散列表/字典,因此降低了性能。
我可以通過使其中存儲一些用於在調用「功能」本身的參數的數據的函子(如「其它基因」如說發電機,其隨機產生的基因)處理的功能。這需要我爲每個函數創建一個新類,以便處理需要唯一參數的每個函數的這種情況。即使在那時,我也不能說當前的基因列表,genotype
轉換成othermutation
而在函數本身的執行過程中不會創建函數列表(所以不是所有的函數都不能作爲mutation_list
在mutate
。
不過我可能只需要忍辱負重,分離需要某些類型的他人提供的信息,如果我想有處理的通用mutation_list
的一個很好的方式有些突變類型,我可以只通過在兩種類型的突變列表
我還可以做一個類似的事情,通過使另一個基因參數成爲函子的靜態函數/變量,所有的實例化都會有。
所以總結了三種方法:
通所有參數通過參數對象,函數挑選哪些參數,他們需要;
使用*參數有效地做同樣的事情,但你也需要一個關聯函數爲每個簽名提取數據;
或者使用函數(帶有或不帶有靜態變量)來保存數據,並使用另一個單獨傳入的突變函數的突變列表,其中調用
mutation
之前無法確定額外的參數。
我想避免讓我的mutate函數關心底層突變是什麼,這樣它可以是通用的儘可能。