473,404 Members | 2,170 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,404 software developers and data experts.

class variables for subclasses tuple

Hello,

I have got a problem that i can't readily solve.
I want the following:
I want to create a supertuple that behaves both as a tuple and as a
class.
It should do the following:
Point=superTuple("x","y","z") # this is a class factory
p=Point(4,7,9)
assert p.x==p[0]
assert p.y==p[1]
assert p.z==p[2]
I already found a recipe to do that (recipe 6.7 in the Python
cookbook). I reproduce the code hereunder:
def superTuple(*attribute_names):
" create and return a subclass of `tuple', with named attributes "
# make the subclass with appropriate _ _new_ _ and _ _repr_ _
specials
typename='Supertuple'
nargs = len(attribute_names)
class supertup(tuple):
_ _slots_ _ = ( ) # save memory, we don't need
per-instance dict
def _ _new_ _(cls, *args):
if len(args) != nargs:
raise TypeError, '%s takes exactly %d arguments (%d
given)' % (
typename, nargs, len(args))
return tuple._ _new_ _(cls, args)
def _ _repr_ _(self):
return '%s(%s)' % (typename, ', '.join(map(repr, self)))
# add a few key touches to our new subclass of `tuple'
for index, attr_name in enumerate(attribute_names):
setattr(supertup, attr_name, property(itemgetter(index)))
supertup._ _name_ _ = typename
return supertup

Now my problem is: i would like to extend this supertuple with class
variables so that i can obtain the following:
assert Point.x==0
assert Point.y==1
assert Point.z==2
while still having:
assert p.x==p[0]
assert p.y==p[1]
assert p.z==p[2]
This is not the case unfortunately:
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.
Alain

Mar 8 '06 #1
6 1546
al********@yahoo.fr 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

Mar 8 '06 #2

Peter Otten wrote:
al********@yahoo.fr 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 ;-)
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

Mar 8 '06 #3
As an supplement to my previous post, please find hereunder a snippet
for my unsuccessful attempt (commented out snippet does not work):
def superTuple(*attribute_names):
nargs = len(attribute_names)
class T(tuple):
def __new__(cls, *args):
return tuple.__new__(cls, args)
class __metaclass__(type):
x=property(lambda self:0)
y=property(lambda self:1)
z=property(lambda self:2)
x=property(lambda self:self[0])
y=property(lambda self:self[1])
z=property(lambda self:self[2])
#for idx, attr_name in enumerate(attribute_names):
# print 'attr name',attr_name, idx
# setattr(T.__metaclass__,attr_name, property(lambda cls:idx))
#for idx, attr_name in enumerate(attribute_names):
# print 'attr name',attr_name
# setattr(T,attr_name, property(lambda self:self[idx]))
return T
if __name__ == '__main__':
Point=superTuple('x','y','z')
p=Point(4,7,9)
assert p.x==p[0]
assert p.y==p[1]
assert p.z==p[2]
assert Point.x==0
assert Point.y==1
assert Point.z==2

Alain

Mar 8 '06 #4
al********@yahoo.fr wrote:

Peter Otten wrote:
al********@yahoo.fr 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

Mar 8 '06 #5
Thank you Peter, this does the job.
In passing, I have another question: where can I read up more on
metaclasses?
Alain

Mar 8 '06 #6
al********@yahoo.fr wrote:
In passing, I have another question: where can I read up more on
metaclasses?


Well, in "Python in a Nutshell" Alex Martelli manages to pack the practical
information that lets you work with metaclasses into just four pages,
including a two-page example. You may have seen posts by Alex on c.l.py
that are longer...

Peter
Mar 8 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
by: Lord Labakudas | last post by:
Hi, I have a very simple question. Is int a predefined class in the standard C++ library. If yes, is it typedef'd as int somewhere ? I wish to know this because, I wish to create a class that...
8
by: Jackson | last post by:
I want a class that will determine its base class by the argument passed in. What I am about to write _does_not_work_, but it shows what I am trying to do. class ABC(some_super): def...
3
by: Janos | last post by:
Hi, I am a newbie, learning C#. I try to map the concepts I have learned earlier in other OO languages to the concepts used here in C# . In Smalltalk you have class variable, which is here the...
21
by: Mr.SpOOn | last post by:
Hi, I'm going to work on a project to represent some musical theory in Python, in an object oriented way. I have to manage many elements of music such as notes, intervals, scales, chords and so...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.