2012-11-23 150 views
2

我知道沒有這樣的事情。這就是爲什麼我在尋找一些不錯的等價物。有這個類:python室內設計師

class MyClass: 
    a = 5 
    b = "foo" 
    c = False 

我想「組」字段a和b在一起,以便能夠以某種方式迭代成員只能從這個組中。因此,這將是不錯的某種場裝飾,如:

class MyClass: 
    @bar 
    a = 5 
    @bar 
    b = "foo" 
    c = False 

而且有像MYDIR(MyClass的,「巴」)的一些功能,將返回(「A」,「B」)。

到目前爲止我們有哪些選擇? 1.按照'a_bar','b_bar'等特殊慣例命名這些字段 - 但不幸的是我無法做到這一點。 2.創建一個名稱列表作爲另一個類成員 - 我想保持這個分組屬性接近屬性,所以我不喜歡這種方法。 3.而不是將'a'和'foo'分配給5我可以使類繼承整數和字符串,並添加另一個基類,如'組',然後檢查類型 - 這種方式,我將不得不生成這個每次我有新類型的課程,所以我也不喜歡這個解決方案。

還有其他想法嗎?

+3

我會說#2是要走的路。這是迄今爲止最簡單,最簡單的方法。 – delnan

+0

所以我忘了寫 - 我想從這個列表中獲得一些想法;) – mnowotka

+0

您的意思是「保持這個分組屬性接近屬性」是什麼意思?您是否指代字典的鍵值存儲屬性? – abought

回答

2

裝飾只是SY函數調用ntactic糖,這樣的裝飾應用到屬性,你只需要調用它的初始化器:

在你的情況,你可以創建實現描述符協議對象:

class GroupedAttribute(object): 
    def __init__(self, group, obj): 
     self.group = group 
     self.obj = obj 
    def __get__(self, obj, owner): 
     return self.obj 
    def __set__(self, obj, value): 
     self.obj = value 

高雅,你可以寫一個類屬性組:

class GroupedAttribute(object): 
    def __init__(self, group, obj): 
     self.group = group 
     self.obj = obj 
    def __get__(self, obj, owner): 
     return self.obj 
    def __set__(self, obj, value): 
     self.obj = value 

class AttributeGroup(object): 
    def __call__(self, obj): 
     return GroupedAttribute(self, obj) 
    def __get__(self, obj, owner): 
     return BoundAttributeGroup(self, obj, owner) 

class BoundAttributeGroup(object): 
    def __init__(self, group, obj, owner): 
     self.group = group 
     self.obj = obj 
     self.owner = owner 
    def __dir__(self): 
     items = dir(self.owner if self.obj is None else self.obj) 
     return [item for item in items if 
       getattr(self.owner.__dict__.get(item, None), 
         'group', None) is self.group] 

用法:

class MyClass(object): 
    bar = AttributeGroup() 
    a = bar(5) 
    b = bar("foo") 
    c = False 
dir(MyClass.bar) # ['a', 'b'] 
+0

我想這可能是一個很好的答案,但坦率地說,我只是你不理解它,你可以擴展它,並給出一個如何實際使用你的代碼的例子嗎? – mnowotka

+0

描述符是一個對象,一旦設置了屬性,將exe可愛的任意代碼,如果你得到或設置此屬性。 @ecatmur通過創建一個描述符來爲您提供解決方案,該描述符將正常設置和獲取屬性,但另外通過您在初始化時向其提供的名稱添加組屬性。 –

+0

我會將這個答案標記爲已接受,但實際上這個答案是@delnan在評論中給出的答案。 – mnowotka

0

如果您希望保留變量名稱以備後用,可以使用字典。如果你想保持變量名

objectName = myObject() 
objectName.dict_bar_props["a"] 
>> 5 

:因此,此代碼的對象內部...

self.dict_bar_props = {} 

self.dict_bar_props["a"] = 5 
self.dict_bar_props["b"] = "foo" 
self.dict_bar_props["c"] = False 

...會給你這樣的結果,當你訪問該對象的後財產完全獨立的,但後來發現他們基於定義的命名約定,那麼你可以使用的東西哈克僅返回與「bar_」爲前綴的變量名,如:

import re 
varnames = dir(objectName) 
list_of_property_names = [ a for a in varnames if re.match("bar_", a) ] 
+0

我很抱歉地說,但似乎你不明白的問題:( – mnowotka

+0

至於字典是你的「相關領域的組」,你絕對可以迭代內部的項目,使用dict_bar_props.keys()/ values()or dict_bar_props.iteritems()。你可能提供了一個預期行爲的例子,來說明這將不能滿足你的需求嗎? – abought

+0

我還添加了第二個解決方案,它是一個稍微低維護的混合體選項1和2 – abought