簡體   English   中英

傳遞集合參數而不解包其內容

[英]Passing a collection argument without unpacking its contents

問題:編寫__init__直接將集合作為參數而不是解壓縮其內容的利弊是什么?

上下文:我正在編寫一個類來處理數據庫表中多個字段的數據。 我遍歷一些大的(約1億行)查詢結果,一次將一行傳遞給執行該處理的類。 每行都作為元組(或可選地,作為字典)從數據庫中檢索。

討論:假設我對三個字段完全感興趣,但是傳遞給我的類的內容取決於查詢,而查詢是由用戶編寫的。 最基本的方法可能是以下之一:

class Direct:
    def __init__(self, names):
        self.names = names

class Simple:
    def __init__(self, names):
        self.name1 = names[0]
        self.name2 = names[1]
        self.name3 = names[2]

class Unpack:
    def __init__(self, names):
        self.name1, self.name2, self.name3 = names

以下是一些可能傳遞給新實例的行的示例:

good = ('Simon', 'Marie', 'Kent')                 # Exactly what we want
bad1 = ('Simon', 'Marie', 'Kent', '10 Main St')   # Extra field(s) behind
bad2 = ('15', 'Simon', 'Marie', 'Kent')           # Extra field(s) in front
bad3 = ('Simon', 'Marie')                         # Forgot a field

面對上述情況, Direct始終可以運行(至少到現在為止),但很可能是越野車(GIGO)。 它接受一個參數並完全按照給定的方式分配它,因此它可以是任何大小的元組或列表,Null值,函數引用等。這是我想到的最快捷,最骯臟的方法對象,但我覺得該類在給它提供顯然不是旨在處理的數據時應該立即抱怨。

Simple手柄bad1正確,因為當車bad2 ,並給予時拋出一個錯誤bad3 能夠有效截斷來自bad1的輸入但不值得來自bad1的錯誤是很bad2 這一個人感到天真和前后矛盾。

Unpack似乎是最安全的方法,因為它在所有三個“不良”情況下都會引發錯誤。 我們要做的最后一件事就是以無提示的信息靜默地填充數據庫,對嗎? 它直接使用元組,但是允許我將其內容標識為不同的屬性,而不是強迫我繼續引用索引,並且抱怨元組的大小是否錯誤。

另一方面,為什么要全部通過收藏呢? 因為我知道我一直想要三個字段,所以我可以定義__init__以顯式地接受三個參數,並在將其傳遞給新對象時使用* -operator解壓縮該集合:

class Explicit:
    def __init__(self, name1, name2, name3):
        self.name1 = name1
        self.name2 = name2
        self.name3 = name3

names = ('Guy', 'Rose', 'Deb')
e = Explicit(*names)

我看到的唯一區別是__init__定義更加冗長,當元組的大小錯誤時,我們將TypeError而不是ValueError 從哲學上講,如果我們要獲取一組數據(查詢的一行)並檢查其部分(三個字段),則應該傳遞一組數據(元組),但要存儲其部分(三個屬性)。 所以Unpack會更好。

如果我想接受不確定數量的字段,而不是三個字段,我仍然可以選擇直接傳遞元組或使用任意參數列表(* args,** kwargs)和* -operator unpacking。 所以我想知道,這是一個完全中立的風格決定嗎?

通過嘗試不同的方法並查看最適合您的方法, 以及其他閱讀您的代碼的人員最容易理解的方法,可能可以最好地回答此問題。

現在,我可以從更多的經驗中受益,我會問自己,我打算如何計划使用這些價值?

當我訪問此集合中的任何一個值時,是否可能在同一子例程或代碼部分中使用大多數或所有值? 如果是這樣,“直接”方法是一個不錯的選擇 它是最緊湊的,它使我可以將集合視為一個集合,直到我絕對需要注意其中的內容為止。

另一方面,如果我在此處使用某些值,在此處使用某些值,那么當我直接引用值時,我就不必一直記住要使用哪個索引來訪問或以字典鍵的形式添加冗長性使用單獨命名的屬性。 在這種情況下,我可能會避免使用“直接”方法,這樣,我什至只需要考慮在首次初始化類時就有一個集合這一事實。

其余的每種方法都涉及將集合分成不同的屬性,我認為明顯的贏家是“顯式”方法 “簡單”和“解壓”方法在收集順序上共享隱藏的依賴性,而沒有提供任何真正的優勢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM