Objects with different data views

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Steven D'Aprano

    #1

    Objects with different data views

    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.

  • Fredrik Lundh

    #2
    Re: Objects with different data views

    Steven D'Aprano wrote:
    [color=blue]
    > 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.[/color]



    </F>



    Comment

    • Paul Rubin

      #3
      Re: Objects with different data views

      Steven D'Aprano <steve@REMOVETH IScyber.com.au> writes:[color=blue]
      > Anyone have any good ideas for how I should implement this?[/color]

      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

      Comment

      • D.Hering

        #4
        Re: Objects with different data views

        Paul Rubin wrote:[color=blue]
        > Steven D'Aprano <steve@REMOVETH IScyber.com.au> 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[/color]

        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)

        Comment

        • Paul Rubin

          #5
          Re: Objects with different data views

          Yeah, that's what I meant. Thanks.

          Comment

          • George Sakkis

            #6
            Re: Objects with different data views

            "Steven D'Aprano" <steve@REMOVETH IScyber.com.au> wrote:
            [color=blue]
            > 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?[/color]

            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


            Comment

            Working...