[NEWBIE]-Object referencing??

Bengt Richter bokr at oz.net
Wed Jul 3 16:03:45 EDT 2002


On Tue, 2 Jul 2002 15:46:36 +1000, "Alistair Campbell" <campbells4 at ozemail.com.au> wrote:

>Hi,
>
>I have class defined as below
>
><code>
>...
>class Brew:
>
>    def __init__(self):
>        self.brew_id=""
>        self.brew_date=""
>        self.brew_type=""
>        self.hydro_init='1040'
>        self.hydro_final='1000'
>        self.starter=""
>        self.amt_start=""
>
>    def alcohol(self):
>        return
>((string.atoi(self.hydro_init)-string.atoi(self.hydro_final))*0.00036251)*10
>0
>...
><code>
>
>I assign data from a file so the data that goes into the alcohol method
>needs to be converted from string.
>The problem is that when I try to reference an instantiation of the Brew()
>class, i.e;
>
>current_brew=Brew()
>
>I can get all the other data items but a call to;
>
>current_brew.alcohol
>
>returns
>
><bound method Brew.alcohol of <__main__.Brew instance at 0x01761250>
>
>So. I know that the calculation of alcohol content is not true but I am just
>fiddling and will put in the correct formula when I get round to it.
>
>But, what am I doing wrong in relation to my definition or calling of the
>Brew.alcohol method?
>
>Trivial but nonetheless I have to start learning somewhere. Your help is
>much appreciated.
>
Other posts haven't revealed that you actually can make it so you can
write current_brew.alcohol and get a calculated value much as if you
called your current_brew.alcohol() method explicitly.

The mechanism is called a property. Using this mechanism, you could write your code as:
( I'm using Python 2.2 (#28, Dec 21 2001, 12:21:22) [MSC 32 bit (Intel)] on win32 )

 >>> class Brew(object):
 ...     def __init__(self):
 ...         self.brew_id=""
 ...         self.brew_date=""
 ...         self.brew_type=""
 ...         self.hydro_init=1040
 ...         self.hydro_final=1000
 ...         self.starter=""
 ...         self.amt_start=""
 ...     def _get_alcohol(self):
 ...         return (self.hydro_init-self.hydro_final)*0.036251 # 0.00036251*100
 ...     def _no_no(self,*args):
 ...         raise TypeError, 'alcohol is a dynamically calculated read-only value. See Brew.alcohol.__doc__'
 ...     alcohol = property(
 ...         _get_alcohol,  # get fcn
 ...         _no_no,        # set fcn
 ...         doc = 'alcohol is calculated as (hydro_init - hydro_final)*0.00036251*100: see those attributes'
 ...     )
 ...

Below, for cb read current_brew ;-)

 >>> cb = Brew()
 >>> cb.alcohol
 1.45004

Now we'll change values it depends on:
 >>> cb.hydro_final -= 40
 >>> cb.alcohol
 2.90008
 >>> cb.hydro_init += 40
 >>> cb.alcohol
 4.3501199999999995

Try to change it as if it were an ordinary attribute. We have defined a set fcn, so we get:
 >>> cb.alcohol = 1.2
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
   File "<stdin>", line 13, in _no_no
 TypeError: alcohol is a dynamically calculated read-only value. See Brew.alcohol.__doc__

But we didn't specify a del fcn after that in property(...), so we get the default response:
 >>> del cb.alcohol
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 AttributeError: can't delete attribute

We did define a doc string for the property, but you have to access it via the class itself
 >>> Brew.alcohol.__doc__
 'alcohol is calculated as (hydro_init - hydro_final)*0.00036251*100: see those attributes'



More about properties: http://www.python.org/2.2/descrintro.html#property

BTW, note that .alcohol is an attribute of the class, but the magic execution
of _get_alcohol() depends on accessing the attribute via a class _instance_:

 >>> cb.alcohol
 4.3501199999999995
 >>> Brew.alcohol
 <property object at 0x007D1BD0>

Also note that you have to derive your class from object to get the property magic.
HTH

Regards,
Bengt Richter



More information about the Python-list mailing list