Objects with different data views

Discussion in 'Python' started by Fredrik Lundh, Oct 7, 2005.

  1. Fredrik Lundh, Oct 7, 2005
    #1
    1. Advertising

  2. 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.
    Steven D'Aprano, Oct 7, 2005
    #2
    1. Advertising

  3. Fredrik Lundh

    Paul Rubin Guest

    Steven D'Aprano <> 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
    Paul Rubin, Oct 7, 2005
    #3
  4. Fredrik Lundh

    D.Hering Guest

    Paul Rubin wrote:
    > Steven D'Aprano <> 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)
    D.Hering, Oct 7, 2005
    #4
  5. Fredrik Lundh

    Paul Rubin Guest

    Yeah, that's what I meant. Thanks.
    Paul Rubin, Oct 7, 2005
    #5
  6. "Steven D'Aprano" <> 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/Cookbook/Python/Recipe/410698.

    HTH,
    George
    George Sakkis, Oct 8, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Doug Mazzacua

    Different Views in Different Browsers

    Doug Mazzacua, Dec 8, 2005, in forum: HTML
    Replies:
    7
    Views:
    442
    Mark Parnell
    Dec 14, 2005
  2. Replies:
    5
    Views:
    392
  3. Brandon McCombs

    using threads with 2 different GUI views

    Brandon McCombs, Jan 10, 2007, in forum: Java
    Replies:
    0
    Views:
    309
    Brandon McCombs
    Jan 10, 2007
  4. toton
    Replies:
    0
    Views:
    302
    toton
    Oct 28, 2006
  5. Andy B
    Replies:
    2
    Views:
    305
    Andy B
    Nov 27, 2007
Loading...

Share This Page