properties setting each other

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • mk

    #1

    properties setting each other

    Hello everyone,

    I try to set two properties, "value" and "square" in the following code,
    and arrange it in such way that setting one property also sets another
    one and vice versa. But the code seems to get Python into infinite loop:
    >>import math
    >>class Squared2(object ):
    def __init__(self, val):
    self._internalv al=val
    self.square=pow (self._internal val,2)

    def fgetvalue(self) :
    return self._internalv al

    def fsetvalue(self, val):
    self._internalv al=val
    self.square=pow (self._internal val,2)

    value = property(fgetva lue, fsetvalue)

    def fgetsquare(self ):
    return self.square
    def fsetsquare(self ,s):
    self.square = s
    self.value = math.sqrt(self. square)

    square = property(fgetsq uare, fsetsquare)

    >>a=Squared2( 5)
    Traceback (most recent call last):
    File "<pyshell#1 1>", line 1, in <module>
    a=Squared2(5)
    File "<pyshell#1 0>", line 5, in __init__
    self.square=pow (self._internal val,2)
    File "<pyshell#1 0>", line 19, in fsetsquare
    self.square = s
    File "<pyshell#1 0>", line 19, in fsetsquare
    self.square = s
    File "<pyshell#1 0>", line 19, in fsetsquare
    self.square = s
    File "<pyshell#1 0>", line 19, in fsetsquare
    self.square = s
    File "<pyshell#1 0>", line 19, in fsetsquare
    self.square = s
    File "<pyshell#1 0>", line 19, in fsetsquare

    ....

    Is there a way to achieve this goal of two mutually setting properties?

  • Wojtek Walczak

    #2
    Re: properties setting each other

    On Wed, 03 Sep 2008 15:57:50 +0200, mk wrote:
    I try to set two properties, "value" and "square" in the following code,
    and arrange it in such way that setting one property also sets another
    one and vice versa. But the code seems to get Python into infinite loop:
    Is there a way to achieve this goal of two mutually setting properties?
    My attempt:
    ---
    import math

    class Square(object):
    def __init__(self, val):
    self._square = pow(val, 2)
    self._value = math.sqrt(self. square)

    def getsquare(self) :
    return self._square

    def setsquare(self, square):
    self._square = square
    self._value = math.sqrt(self. _square)

    square = property(getsqu are, setsquare)

    def getvalue(self):
    return self._value

    def setvalue(self, value):
    self._value = value
    self._square = math.pow(value, 2)

    value = property(getval ue, setvalue)


    a = Square(5)
    print a.square
    print a.value
    a.value = 10
    print a.square
    print a.value
    a.square = 64
    print a.square
    print a.value
    ---

    and the result:

    $ python sqval.py
    25
    5.0
    100.0
    10
    64
    8.0
    $

    --
    Regards,
    Wojtek Walczak,
    http://tosh.pl/gminick/

    Comment

    • Wojtek Walczak

      #3
      Re: properties setting each other

      On Wed, 3 Sep 2008 14:31:17 +0000 (UTC), Wojtek Walczak wrote:
      class Square(object):
      def __init__(self, val):
      self._square = pow(val, 2)
      self._value = math.sqrt(self. square)
      ^^^^^^^^^^^^^^^ ^^^^^^^
      or just:
      self._value = val

      :-)


      --
      Regards,
      Wojtek Walczak,
      http://tosh.pl/gminick/

      Comment

      • Diez B. Roggisch

        #4
        Re: properties setting each other

        mk schrieb:
        Hello everyone,
        >
        I try to set two properties, "value" and "square" in the following code,
        and arrange it in such way that setting one property also sets another
        one and vice versa. But the code seems to get Python into infinite loop:
        >
        >>import math
        >>class Squared2(object ):
        >
        def __init__(self, val):
        self._internalv al=val
        self.square=pow (self._internal val,2)
        >
        def fgetvalue(self) :
        return self._internalv al
        >
        def fsetvalue(self, val):
        self._internalv al=val
        self.square=pow (self._internal val,2)
        >
        value = property(fgetva lue, fsetvalue)
        >
        def fgetsquare(self ):
        return self.square
        def fsetsquare(self ,s):
        self.square = s
        self.value = math.sqrt(self. square)
        >
        square = property(fgetsq uare, fsetsquare)
        >
        >
        >>a=Squared2( 5)
        >
        Traceback (most recent call last):
        File "<pyshell#1 1>", line 1, in <module>
        a=Squared2(5)
        File "<pyshell#1 0>", line 5, in __init__
        self.square=pow (self._internal val,2)
        File "<pyshell#1 0>", line 19, in fsetsquare
        self.square = s
        File "<pyshell#1 0>", line 19, in fsetsquare
        self.square = s
        File "<pyshell#1 0>", line 19, in fsetsquare
        self.square = s
        File "<pyshell#1 0>", line 19, in fsetsquare
        self.square = s
        File "<pyshell#1 0>", line 19, in fsetsquare
        self.square = s
        File "<pyshell#1 0>", line 19, in fsetsquare
        >
        ...
        >
        Is there a way to achieve this goal of two mutually setting properties?
        >
        Better to make the getter for square return the square of value, and the
        setter of square compute the root & set that. Like this:

        class Squared2(object ):

        def __init__(self, value):
        self.value = value


        @apply
        def squared():
        def fset(self, squared):
        self.value = math.sqrt(squar ed)

        def fget(self):
        return self.value ** 2

        return property(**loca ls())

        Diez

        Comment

        • Bruno Desthuilliers

          #5
          Re: properties setting each other

          mk a écrit :
          Hello everyone,
          >
          I try to set two properties, "value" and "square" in the following code,
          and arrange it in such way that setting one property also sets another
          one and vice versa. But the code seems to get Python into infinite loop:
          >
          >>import math
          >>class Squared2(object ):
          >
          def __init__(self, val):
          self._internalv al=val
          self.square=pow (self._internal val,2)
          the 'internal' prefix is already implied by the '_'. And your __init__
          code is a useless duplication of fsetvalue, so just use the property and
          get rid of copy-pasted code.

          def fgetvalue(self) :
          return self._internalv al
          the '_' prefix already means 'internal'. The convention here would be to
          name the attribute '_value' (to make clear it's the implementation
          support for the 'value' property). Also, your property getter and setter
          should also be marked as implementation using the '_' prefix - they are
          implementation detail, not part of your class API.
          def fsetvalue(self, val):
          self._internalv al=val
          self.square=pow (self._internal val,2)
          >
          value = property(fgetva lue, fsetvalue)
          >
          def fgetsquare(self ):
          return self.square
          def fsetsquare(self ,s):
          self.square = s
          Hem... Notice something here ?
          self.value = math.sqrt(self. square)
          >
          square = property(fgetsq uare, fsetsquare)
          Your fsetsquare implementation is broken - it calls itself recursively.
          You have to use different names for the property and the 'implementation
          attribute' for the property. But even if you fix this, you'll have
          another infinite recursion between the two setters.

          The simplest solution : don't call one property from the other, do
          direct attribute access within the setters:

          import math

          class Squared2(object ):
          def __init__(self, value):
          self.value=valu e

          def _fgetvalue(self ):
          return self._value
          def _fsetvalue(self , value):
          self._value=val ue
          self._square=po w(value,2)
          value = property(_fgetv alue, _fsetvalue)

          def _fgetsquare(sel f):
          return self._square
          def _fsetsquare(sel f,square):
          self._square = square
          self._value = math.sqrt(squar e)
          square = property(_fgets quare, _fsetsquare)


          Comment

          Working...