Velocity Reviews > Objects with different data views

# Objects with different data views

Fredrik Lundh
Guest
Posts: n/a

 10-07-2005
Steven D'Aprano wrote:

> It is important that there are no privileged attributes, e.g. in the
> above example, I can set any of x, y, z, r, theta or phi and all the
> others will automatically reflect the changes.

http://users.rcn.com/python/download...htm#properties

</F>

Steven D'Aprano
Guest
Posts: n/a

 10-07-2005
I'm not sure how to do this, or where to start looking for the right
information, so any advice would be appreciated.

I want to implement a class with two (or more) different ways of looking
at its attributes.

One example of this might be complex numbers, which can be written in
Cartesian form (x+yi) or polar form (r cis theta).

(Yes, I know Python already has complex numbers. That was just an example.)

Another might be 3D vectors, which can be written in Cartesian form
[x, y, z], polar form [r, theta, z] or spherical polar [r, theta, phi].

It is important that there are no privileged attributes, e.g. in the
above example, I can set any of x, y, z, r, theta or phi and all the
others will automatically reflect the changes. A concrete, if simple,
example will make it clear.

Suppose I have a transformation (a,b) <-> (x,y) where:

x = a+b
y = a+2*b

I create an instance spam, and set a and b:

spam.a = 1
spam.b = 2

Now I should be able to read x and y:

print spam.x, spam.y
# prints 3 5

If I set attribute y:

spam.y = 0

a and b automatically change to match:

print spam.a, spam.b
# prints 6, -3

Anyone have any good ideas for how I should implement this?

Thanks,

--
Steven.

Paul Rubin
Guest
Posts: n/a

 10-07-2005
Steven D'Aprano <(E-Mail Removed)> writes:
> Anyone have any good ideas for how I should implement this?

These days you can use properties. Before, you'd have had to do it
manually with __setattr__ / __getattr__ methods. Here's how I'd do it
with properties, if I have the math right. You're using a and b as
the canonical values of the variables, computing x and y from them,
and adjusting them when x and y change.

class Parrot(object):
x = property(getx, setx)
y = property(gety, sety)

def getx(self):
return self.a + self.b
def setx(self, x):
y = self.y # calls gety
self.a, self.b = 2*x - y, y-x

def gety(self):
return self.a + 2*self.b
def sety(self, y):
x = self.x # calls getx
self.a, self.b = 2*x - y, y-x

D.Hering
Guest
Posts: n/a

 10-07-2005
Paul Rubin wrote:
> Steven D'Aprano <(E-Mail Removed)> writes:
>
> class Parrot(object):
> x = property(getx, setx)
> y = property(gety, sety)
>
> def getx(self):
> return self.a + self.b
> def setx(self, x):
> y = self.y # calls gety
> self.a, self.b = 2*x - y, y-x
>
> def gety(self):
> return self.a + 2*self.b
> def sety(self, y):
> x = self.x # calls getx
> self.a, self.b = 2*x - y, y-x

class Parrot(object):

def getx(self):
return self.a + self.b
def setx(self, x):
y = self.y # calls gety
self.a, self.b = 2*x - y, y-x

def gety(self):
return self.a + 2*self.b
def sety(self, y):
x = self.x # calls getx
self.a, self.b = 2*x - y, y-x

x = property(getx, setx)
y = property(gety, sety)

Paul Rubin
Guest
Posts: n/a

 10-07-2005
Yeah, that's what I meant. Thanks.

George Sakkis
Guest
Posts: n/a

 10-08-2005
"Steven D'Aprano" <(E-Mail Removed)> wrote:

> I'm not sure how to do this, or where to start looking for the right
> information, so any advice would be appreciated.
>
> I want to implement a class with two (or more) different ways of looking
> at its attributes.
>
> One example of this might be complex numbers, which can be written in
> Cartesian form (x+yi) or polar form (r cis theta).
>
> (Yes, I know Python already has complex numbers. That was just an example.)
>
> Another might be 3D vectors, which can be written in Cartesian form
> [x, y, z], polar form [r, theta, z] or spherical polar [r, theta, phi].
>
> It is important that there are no privileged attributes, e.g. in the
> above example, I can set any of x, y, z, r, theta or phi and all the
> others will automatically reflect the changes. A concrete, if simple,
> example will make it clear.
>
> Suppose I have a transformation (a,b) <-> (x,y) where:
>
> x = a+b
> y = a+2*b
>
> I create an instance spam, and set a and b:
>
> spam.a = 1
> spam.b = 2
>
> Now I should be able to read x and y:
>
> print spam.x, spam.y
> # prints 3 5
>
> If I set attribute y:
>
> spam.y = 0
>
> a and b automatically change to match:
>
> print spam.a, spam.b
> # prints 6, -3
>
>
> Anyone have any good ideas for how I should implement this?

As others have replied, properties is the way to go. There have been a few recipes in the Cookbook
that avoid cluttering the class namespace with temporary get/set/del methods, e.g.
http://aspn.activestate.com/ASPN/Coo.../Recipe/410698.

HTH,
George

 Thread Tools

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post Brandon McCombs Java 0 01-10-2007 04:07 AM toton C++ 0 10-28-2006 12:10 PM ActionNotMotion@gmail.com HTML 5 06-16-2006 05:20 PM Doug Mazzacua HTML 7 12-14-2005 04:49 AM Z Firefox 6 06-22-2005 05:14 PM

Advertisments