2010-02-15 104 views
8

使用for循環,我試圖從字典生成類:添加類屬性在Python

class attr: 
    for key in objects_type: 
     setattr(attr, key, lambda cl: list()) 

這給attr屬性沒有在for循環中定義的錯誤。我知道我可以寫:

class attr: 
    pass 
for key in objects_type: 
    setattr(attr, key, lambda cl: list()) 

但我相信我記得看到類似於第一個示例代碼的某個地方。有誰知道是否有可能寫出類似於第一種形式的東西?

回答

6

儘管這不是很優雅,你可以使用locals()

>>> class c(object): 
...  for i in range(10): 
...   locals()['A' + str(i)] = i 
... 
>>> c.A0 
0 
>>> c.A7 
7 
+0

這一定是我記得看到的。感謝 – Casebash 2010-02-15 11:17:40

+0

事實上,我認爲它比使用setattr更好 - 所以我不會說它不雅的 – Casebash 2010-02-15 11:19:13

+6

你不應該改變本地()字典:http://docs.python.org/library/functions .html#本地人 – stephan 2010-02-15 11:27:21

2

我不完全知道,你在做什麼。我可以給你舉個例子,在for循環中向類中添加類屬性:

attributes = ('x', 5), ('y', 6), ('name', 'Cls') 

class Cls: 
    pass 
for key, value in attributes: 
    setattr(Cls, key, value) 

請記住,必須在定義整個類之後運行。你會得到錯誤,該attr沒有定義,因爲你想訪問類之前你創建它class ...是在Python中,它創建一個類對象)的語句。創建類並記住之後,必須添加屬性,這些屬性將是類屬性,而不是實例屬性。

1
class Attr: 
    def __init__(self): 
    for key in objects_type: 
     setattr(Attr, key, lambda cl: list()) 
+1

+1:好。爲什麼不是從'object'繼承的「新風格」類? – 2010-02-15 11:11:50

+2

這是做錯的地方。它不僅浪費,而且現有的綁定方法將與稍後實例化的綁定方法不同。那麼,比平常更多不同。 – 2010-02-15 11:13:13

2
newmeths = { 
    'two': lambda self: 2, 
} 

class MC(type): 
    def __init__(cls, name, bases, dict): 
    for k, v in newmeths.iteritems(): 
     setattr(cls, k, v) 
    super(MC, cls).__init__(name, bases, dict) 

class C(object): 
    __metaclass__ = MC 
    pass 

c=C() 
print c.two() 
3

假設你要動態地添加類屬性,如這些

classDict = {} 
for i in range(2): 
    classDict["func%s"%(i+1)] = lambda self:"X" 

你可以這樣做在幾個方面,例如剛下課已經被創建之後,因爲你can'y內輕鬆訪問類的類名

class Attr2(object): 
    pass 

for n,v in classDict.iteritems(): 
    setattr(Attr2, n, v) 

print Attr2().func1(), Attr2().func2() 

或更好的只是動態創建類例如添加屬性

Attr3 = type("Attr3",(), classDict) 
print Attr3().func1(), Attr3().func2() 

,或者如果你要使用元類e.g

class AttrMeta(type): 
    def __new__(cls, name, bases, dct): 
     dct.update(classDict) 
     return type.__new__(cls, name, bases, dct) 

class Attr4(object): 
    __metaclass__ = AttrMeta 

print Attr4().func1(), Attr4().func2() 
+1

我認爲'type'方法是最好的解決方案,給出了這個問題。它確實要求程序員重新構造定義類屬性的其餘部分。另一方面,它避免了挖掘'locals()',避免定義一個自定義元類,並避免使用其他_other_元類的邏輯。國際海事組織,這使得它適合其他人將使用和貢獻的圖書館。 – AlanSE 2017-11-01 21:52:20