[EMAIL PROTECTED] wrote: > > Peter Otten wrote: >> [EMAIL PROTECTED] wrote: >> >> > Point.x=0 leads to having p.x==0 >> > It seems not possible to have class variables and instance variable >> > having the same name and yet different values. >> >> A quick check: >> >> >>> class T(tuple): >> ... class __metaclass__(type): >> ... x = property(lambda cls: 0) >> ... x = property(lambda self: self[0]) >> ... >> >>> t = T("abc") >> >>> t.x >> 'a' >> >>> T.x >> 0 >> >> So possible it is. Come back if you're stuck generalizing the above. >> >> Peter > > Thanks for your magic answer. > But i am not so good at magic ;-)
Once I grokked that a class is just an instance of its metaclass all magic magically vanished :-) > If i want to generalize to a arbitrary number of variables, i got > syntax errors. > Within a class, you can only method/class definitions and assignments. > It is therefore difficult to do something like: > for idx, attr_name in enumerate(attribute_names): > setattr(__metaclass__,attr_name, property(lambda cls:idx) > for idx, attr_name in enumerate(attribute_names): > setattr(T,attr_name, property(lambda self:self[idx]) > > Alain I'm not getting syntax errors: >>> names = "xyz" >>> class T(tuple): ... class __metaclass__(type): ... pass ... for index, name in enumerate(names): ... setattr(__metaclass__, name, property(lambda cls, index=index: index)) ... del index ... del name ... >>> for index, name in enumerate(names): ... setattr(T, name, property(lambda self, index=index: self[index])) ... Traceback (most recent call last): File "<stdin>", line 2, in ? AttributeError: can't set attribute However, the read-only property of the metaclass prevents setting the class attribute. A workaround is to set the class properties /before/ the metaclass properties. Here is a no-frills implementation, mostly untested: from operator import itemgetter def constgetter(value): def get(self): return value return get def make_tuple(*names): class TupleType(type): pass class T(tuple): __metaclass__ = TupleType def __new__(cls, *args): if len(names) != len(args): raise TypeError return tuple.__new__(cls, args) for index, name in enumerate(names): setattr(T, name, property(itemgetter(index))) for index, name in enumerate(names): setattr(TupleType, name, property(constgetter(index))) return T Peter -- http://mail.python.org/mailman/listinfo/python-list