I know there is no such a thing. That's why I'm looking for some nice equivalent. Having this class:
class MyClass:
a = 5
b = "foo"
c = False
I would like to "group" fields a and b together to be able to somehow iterate over members only from this group. So it would be nice to have some kind of field decorator, like:
class MyClass:
@bar
a = 5
@bar
b = "foo"
c = False
And to have some function like myDir(MyClass, 'bar') that would return ('a', 'b').
What options do we have so far? 1. Name these fields by special convention like 'a_bar', 'b_bar' - but I can't do it unfortunately. 2. make a list of names as another class member - I would like to keep this grouping attribute close to attribute so I don't like this approach. 3. Instead of assigning 5 to 'a' and "foo" to be I can make classes that inherit from integer and string and add another base class like 'Group' and then check the types - this way I will have to generate this class each time I have new type, so I don't like this solution either.
Any other ideas?
Decorators are just syntactic sugar for a function call, so to apply a decorator to an attribute you just need to call it on the initialiser:
a = bar(5)
In your case you can create objects that implement the descriptor protocol:
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
For elegance, you could write a class for attribute groups:
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]
Usage:
class MyClass(object):
bar = AttributeGroup()
a = bar(5)
b = bar("foo")
c = False
dir(MyClass.bar) # ['a', 'b']
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With