Hi all, Currently descriptors only work as class attribute, and doesn't work as a descriptor when it is an instance attribute.
e.g. if we have descriptor class DescriptorTest, class Dummy(object): d = DescriptorTest() class Dummy2(object): def __init__(self): self.d = DescriptorTest() The instance of Dummy2 does not invoke the descriptor protocols on "d". Whereas Dummy() instances all share the same descriptor "d". Yes I know d.__get__() have an "instance" parameter which can be used to store per-instance values, but sometimes it is just not enough (or it is that I do not know a better approach exists). Suppose the below scenario, I want to model a "Register". A register is consist of some fields, which have different number of bits. e.g. a 32 bit register divided into 3 field, bit[0] to bit[7] is called M, bit[8] to bit[15] is called N, and bit[16] to bit[31] is called Z. I want to model a register that, when instantiated as "reg", reg.M/N/Z can directly reference each field, calling a descriptor protocol to verify and return the values. Yes, I know I can use metaclass to create a different class for different registers, but that's not seems to be a very smart approach here, as I want all register instances be of type "Register". But the default python protocol will not run descriptor protocols if a descriptor is an instance attribute. I'm sure I should not be the only one that facing this issue and I googled around and found a solution to redefine the __setattr__ and __getattribute__ to look up the descriptor protocols first: 107 def __getattribute__(self, name): 108 value = object.__getattribute__(self, name) 109 if hasattr(value, '__get__'): 110 value = value.__get__(self, self.__class__) 111 return value 112 113 def __setattr__(self, name, value): 114 try: 115 obj = object.__getattribute__(self, name) 116 except AttributeError: 117 pass 118 else: 119 if hasattr(obj, '__set__'): 120 return obj.__set__(self, value) 121 return object.__setattr__(self, name, value) This works like a charm and each instance of "Register" now invoke the descriptors properly. I just do not understand, why such behavior is not a default in python. Or, is there a better design pattern here? Thanks & Best Regards, Hua Yanghao -- http://mail.python.org/mailman/listinfo/python-list