2012-11-23 91 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