我知道没有这样的事情。这就是为什么我正在寻找一些不错的等价物。有这个课程:
class MyClass:
a = 5
b = "foo"
c = False
我想将字段a和b“分组”在一起,以便能够以某种方式迭代来自该组的成员。所以有一些场装饰器会很好,比如:
class MyClass:
@bar
a = 5
@bar
b = "foo"
c = False
有一些像myDir(MyClass,'bar')这样的函数会返回('a','b')。
到目前为止,我们有哪些选择? 1.按照'a_bar','b_bar'之类的特殊约定命名这些字段 - 但遗憾的是我不能这样做。 2.将名称列表作为另一个类成员 - 我想保持这个分组属性接近属性,所以我不喜欢这种方法。 3.而不是将5分配给'a'和'foo',我可以创建继承自整数和字符串的类,并添加另一个基类,如'Group',然后检查类型 - 这样我将不得不生成这个类每次我有新类型,所以我也不喜欢这个解决方案。
还有其他想法吗?
答案 0 :(得分:2)
装饰器只是函数调用的语法糖,因此要将装饰器应用于属性,只需在初始化器上调用它:
a = bar(5)
在您的情况下,您可以创建实现描述符协议的对象:
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']
答案 1 :(得分:0)
如果要保留变量名以便稍后引用,可以使用字典。因此,您的对象中的此代码...
self.dict_bar_props = {}
self.dict_bar_props["a"] = 5
self.dict_bar_props["b"] = "foo"
self.dict_bar_props["c"] = False
...稍后访问该对象的属性时会给你这个结果:
objectName = myObject()
objectName.dict_bar_props["a"]
>> 5
如果你想保持变量名完全分开但稍后根据定义的命名约定找到它们,那么你可以使用hacky,它只返回前缀为“bar_”的变量名,例如:
import re
varnames = dir(objectName)
list_of_property_names = [ a for a in varnames if re.match("bar_", a) ]