2014-04-21 75 views
1

我可以使用元類初始化具有名稱的名稱嗎?它是否安全?我可以使用Python中的元類初始化具有名稱的名稱嗎?它是否安全?

class MetaA(type): 
    def __new__(metaCls, name, bases, clsDict): 
    clsDict['_%s__counter' % name] = 0 
    return super(MetaA, metaCls).__new__(metaCls, name, bases, clsDict) 

class A(object): 
    __metaclass__ = MetaA 

我搜索了,沒有找到明確的解釋。我經常使用損壞的名稱,但很少使用元類,並且不確定它是否有效。'_%s__%s' % (className, attrName) - 它可以工作,但可能不兼容。

+0

@Blckknght元類就像類的工廠,所以你可以使用元類創建許多類,而不是重複代碼或控制代碼鏡像,所以它是避免錯誤的好模式,但它並不經常需要。你不能用OOD實現某些方面,如每個類的單獨初始化類變量不共享它 - 這是不可能的,因爲繼承是不可能的,或者需要爲每個類添加一些代碼來重新初始化某些共享變量以使其不共享(即線程鎖以避免死鎖)。 – Chameleon

回答

0

你要求做的是合法的,並且或多或少是安全的(就像訪問那些名字暗示他們打算是私人的屬性一樣安全)。從設計的角度來看,這可能不是一個好主意。

問題是,爲什麼你首先使用了破損的名字?如果該屬性旨在從多個類訪問(包括類和它的元類的訪問),那麼您可能應該使用unmangled屬性名稱。

如果您經常發現自己需要解決某個屬性的問題,那麼您可能會過度使用錯誤的名稱。使用單個前導下劃線來表明名稱是「私有的」(或者至少不屬於類的穩定的公共API)。

只有少數類需要重名,通常是因爲你希望它們的屬性名稱空間需要保持「乾淨」。例如,一個代理類可能希望它的屬性名稱空間工作,就好像它是一個目標對象的副本。使用重名的名稱可以幫助防止代理的實例變量隱藏任何目標的屬性。

+0

我使用的名稱比_names更頻繁,因爲它會強制執行乾淨的代碼 - 您根本無法使用它們。元類與繼承類不同,它不具有可比性,因爲與類的距離不同而且用法不同 - 它說的差別太大了。考慮帶線程鎖定的簡單示例mangled變量。它應該是可見的 - 不是嗎?必須在元類中可見 - 是嗎?可以由課程初始化 - 不是?可以用對象實例初始化 - 不/是,但它浪費內存?可以通過元類進行初始化 - 是的? – Chameleon

+0

順便說一下,我的代碼風格可以改進,但它可以編寫非常複雜的程序,即500k行代碼,而不會出現大量的錯誤。 – Chameleon

+0

如果你把一些行爲的全部實現放在一個元類中,那麼如果你讓元類以它自己的名字進行修改(即在元類代碼中使用'__attr'),那麼使用修改後的名稱將是有意義的。否則,我仍然認爲最好去一個普通的名字,而不是手動執行元類中的mangling。但是,嘿,好的設計在很大程度上是一個意見問題。正如我在答覆的第一段中所說的那樣,如果你願意的話,撤銷損壞是合法的。如果您覺得有必要使用補丁,我相信您可以使其適用於您的項目。 – Blckknght

相關問題