Google
 
Webnews.only-4-geeks.com
Interesting places
news.only-4-geeks.com Forum Index » PythonGoto page 1, 2  Next

properties setting each other

 
Jump to:  
 
mk
PostPosted: Wed Sep 03, 2008 11:57 am    Post subject: 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:

Quote:
import math
class Squared2(object):

def __init__(self, val):
self._internalval=val
self.square=pow(self._internalval,2)

def fgetvalue(self):
return self._internalval

def fsetvalue(self, val):
self._internalval=val
self.square=pow(self._internalval,2)

value = property(fgetvalue, fsetvalue)

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

square = property(fgetsquare, fsetsquare)


Quote:
a=Squared2(5)

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

....

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

 
Diez B. Roggisch
PostPosted: Wed Sep 03, 2008 12:42 pm    Post subject: Re: properties setting each other
       
mk schrieb:
Quote:
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._internalval=val
self.square=pow(self._internalval,2)

def fgetvalue(self):
return self._internalval

def fsetvalue(self, val):
self._internalval=val
self.square=pow(self._internalval,2)

value = property(fgetvalue, fsetvalue)

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

square = property(fgetsquare, fsetsquare)


a=Squared2(5)

Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module
a=Squared2(5)
File "<pyshell#10>", line 5, in __init__
self.square=pow(self._internalval,2)
File "<pyshell#10>", line 19, in fsetsquare
self.square = s
File "<pyshell#10>", line 19, in fsetsquare
self.square = s
File "<pyshell#10>", line 19, in fsetsquare
self.square = s
File "<pyshell#10>", line 19, in fsetsquare
self.square = s
File "<pyshell#10>", line 19, in fsetsquare
self.square = s
File "<pyshell#10>", 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(squared)

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

return property(**locals())

Diez
 

 
Maric Michaud
PostPosted: Wed Sep 03, 2008 12:44 pm    Post subject: Re: properties setting each other
       
Le Wednesday 03 September 2008 15:57:50 mk, vous avez écrit :
Quote:
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._internalval=val
                self.square=pow(self._internalval,2)
                
        def fgetvalue(self):
                return self._internalval
                
        def fsetvalue(self, val):
                self._internalval=val
                self.square=pow(self._internalval,2)
                
        value = property(fgetvalue, fsetvalue)

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

        
 >>> a=Squared2(5)

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

...

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

Your square property is not correctly defined, it recurselively call itself,
it should be (I also avoided the extra lookup) :

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

then the fsetvalue will be also be called recursively as it use the square
property, you should also write it :

def fsetvalue(self, val):
self._internalval=val
self._square=pow(val,2)

*but*, if you want to add more logic in the setters, you could want to add two
extra methods :

def _setsquare(self, v) :
# some extra logic here
self._square = s

def fsetsquare(self,s):
self._setsquare(s)
self._setvalue = math.sqrt(s)

def _setvalue(self, val):
# some extra logic here
self._internalval=val

def fsetvalue(self, val):
self._setvalue(val)
self._setsquare=pow(val,2)


Note that if one property can really be computed from another, this kind of
thing could be considered as bad design (except if the computation is heavy).

--
_____________

Maric Michaud
 

 
Bruno Desthuilliers
PostPosted: Wed Sep 03, 2008 12:50 pm    Post subject: Re: properties setting each other
       
mk a écrit :
Quote:
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._internalval=val
self.square=pow(self._internalval,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.


Quote:
def fgetvalue(self):
return self._internalval

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.

Quote:
def fsetvalue(self, val):
self._internalval=val
self.square=pow(self._internalval,2)

value = property(fgetvalue, fsetvalue)

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

Hem... Notice something here ?

Quote:
self.value = math.sqrt(self.square)

square = property(fgetsquare, 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=value

def _fgetvalue(self):
return self._value
def _fsetvalue(self, value):
self._value=value
self._square=pow(value,2)
value = property(_fgetvalue, _fsetvalue)

def _fgetsquare(self):
return self._square
def _fsetsquare(self,square):
self._square = square
self._value = math.sqrt(square)
square = property(_fgetsquare, _fsetsquare)
 

 
Maric Michaud
PostPosted: Wed Sep 03, 2008 12:52 pm    Post subject: Re: properties setting each other
       
Le Wednesday 03 September 2008 16:44:10 Maric Michaud, vous avez écrit :
Quote:
         def _setsquare(self, v) :
                 # some extra logic here
                 self._square = s

         def fsetsquare(self,s):
                 self._setsquare(s)
                 self._setvalue = math.sqrt(s)

         def _setvalue(self, val):
                 # some extra logic here
                 self._internalval=val

         def fsetvalue(self, val):
                 self._setvalue(val)
                 self._setsquare=pow(val,2)

Oh sorry for this last version the setters should be :

def fsetsquare(self,s):
self._setsquare(s)
self._setvalue = math.sqrt(self.square)

def fsetvalue(self, val):
self._setvalue(val)
self._setsquare=pow(self.value, 2)

as we don't know what is done in _setXXX methods.

--
_____________

Maric Michaud
 

 
mk
PostPosted: Wed Sep 03, 2008 1:40 pm    Post subject: Re: properties setting each other
       
Thanks to everyone for answers..

Quote:
*but*, if you want to add more logic in the setters, you could want to add two
extra methods :

def _setsquare(self, v) :
# some extra logic here
self._square = s

def fsetsquare(self,s):
self._setsquare(s)
self._setvalue = math.sqrt(s)

def _setvalue(self, val):
# some extra logic here
self._internalval=val

def fsetvalue(self, val):
self._setvalue(val)
self._setsquare=pow(val,2)


Thanks for that, I'll keep that in mind.


Quote:
Note that if one property can really be computed from another, this kind of
thing could be considered as bad design (except if the computation is heavy).

Hmm, why? Is the line of thinking smth like: because the variables
should be kept to minimum and they should be calculated at the moment
they are needed?
 

 
Maric Michaud
PostPosted: Wed Sep 03, 2008 2:11 pm    Post subject: Re: properties setting each other
       
Le Wednesday 03 September 2008 17:40:43 mk, vous avez écrit :
Quote:
Note that if one property can really be computed from another, this kind
of thing could be considered as bad design (except if the computation is
heavy).

Hmm, why? Is the line of thinking smth like: because the variables
should be kept to minimum and they should be calculated at the moment
they are needed?

Because you have to make extra effort to keep the logical relation between
value and square. self._square is not really needed, and what is not needed
is just extra hassle.

Doesn't it clear that your code is more hard to maintain than the
alternative :

class Squared(object):

def __init__(self, val):
self._val=val

def fgetvalue(self):
return self._val
def fsetvalue(self, val):
self._val=val
value = property(fgetvalue, fsetvalue)

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



--
_____________

Maric Michaud
 

 
Wojtek Walczak
PostPosted: Wed Sep 03, 2008 2:31 pm    Post subject: Re: properties setting each other
       
On Wed, 03 Sep 2008 15:57:50 +0200, mk wrote:

Quote:
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(getsquare, setsquare)

def getvalue(self):
return self._value

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

value = property(getvalue, 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,
LINK
 

 
Wojtek Walczak
PostPosted: Wed Sep 03, 2008 2:34 pm    Post subject: Re: properties setting each other
       
On Wed, 3 Sep 2008 14:31:17 +0000 (UTC), Wojtek Walczak wrote:

Quote:
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,
LINK
 

 
Bruno Desthuilliers
PostPosted: Wed Sep 03, 2008 3:38 pm    Post subject: Re: properties setting each other
       
Maric Michaud a écrit :
Quote:
Le Wednesday 03 September 2008 17:40:43 mk, vous avez écrit :
Note that if one property can really be computed from another, this kind
of thing could be considered as bad design (except if the computation is
heavy).
Hmm, why? Is the line of thinking smth like: because the variables
should be kept to minimum and they should be calculated at the moment
they are needed?

Because you have to make extra effort to keep the logical relation between
value and square. self._square is not really needed, and what is not needed
is just extra hassle.

Doesn't it clear that your code is more hard to maintain than the
alternative :

class Squared(object):

def __init__(self, val):
self._val=val

def fgetvalue(self):
return self._val
def fsetvalue(self, val):
self._val=val
value = property(fgetvalue, fsetvalue)

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

FWIW, if there's no computation on getting or setting value, you can
make it a plain attribute.

But while it's quite clear that in this example use case it would be
better to have only one property (weither square or value, depending on
which is the most often use), things are not always that simple in real
world code, and - as you mentionned - there may be times where you have
interdependant properties and really want to avoid recomputing the same
thing over and over. Now there's no one size fits all solution here -
it's an optimization problem, and as such depends on real use cases.
 

Page 1 of 2 .:. Goto page 1, 2  Next

Google
 
Webnews.only-4-geeks.com

Windows Update | C++ | C | PHP | JavaScript | Photoshop | Programming | Windows 2000 | Python | Windows XP | Object | Flash | Flash - ActionScript | Paint Shop Pro | Excel | PowerPoint | Access | Word | Windows 98 | Internet Explorer 6.0 | CorelDraw12 | Java | XML | asm x86 | Linux Mandrake | Linux RedHat | Outlook |  | news from newsgroups |_ | s

Web Templates

Awesome Website Templates ©

GIS Obszary zastosowań przedłużanie włosów reklama konta studenckie HP 83 Magenta UV Value Pack