[Tutor] Concept related to python classes

Alan Gauld alan.gauld at yahoo.co.uk
Mon Sep 7 16:50:58 EDT 2020


On 07/09/2020 17:15, Manprit Singh wrote:
> Dear Sir,
> This is again a continuation mail . I have tried to solve the same problem
> of finding area of a triangle using decorators . and it seems more
> effective in comparison to my previous code, which is given below :

More effective in what sense? You have written a lot of extra code,
introduced a lot of function call overhead and achieved the
same end result that you had to start with. Normally we aim
to reduce complexity in code not to increase it!

> class Triangle:
>     def __init__(self):
>         self._a = None
>         self._b = None
>         self._c = None
>         self._area = None

You have reintroduced an area attribute when we already saw
that it was unnecessary. And you've lost the resize() method
which was helpful to your users.
>     @property
>     def a(self):
>         """I'm the 'a' property."""
>         return self._a
> 
>     @a.setter
>     def a(self, a1):
>         self._a = a1
> 

properties are useful when you want to do something to the attribute -
such as validate the data before assigning it or log the assignment for
auditing changes. But if you only want to  set/get the values they are
pointless and inefficient both in developer time and in execution time.

As an exercise in creating properties this makes some sense, but
as a practical programming idiom it should be avoided.

>     def calcarea(self):
>         s = (self._a + self._b + self._c) / 2
>         self._area =  (s * (s - self._a) * (s - self._b) * (s -
> self._c))**0.5
> 
>     @property
>     def area(self):
>         self.calcarea()
>         return self._area

All you needed to do was call the calculation area and apply the
property decorator. That would allow you to make area look like
it was an attribute but to calculate it on demand.


> tri = Triangle()
> tri.a = 3
> tri.b = 4
> tri.c = 5
> print("Area of triangle with
> sides",tri.a,"&",tri.b,"&",tri.c,"is",tri.area)

If you really want to access the individual attributes external
to the class just access the attributes, you don't need properties.

> Just see, after making the object of the class Triangle and assigning it to
> a variable tri , i am just going in an easy way similar to assigning values
> to the instance variables, 

Correct, although as a user of your class I still prefer resize() since
it's only one line of code and it describes the operation I'm performing
on the object rather than exposing the internal details of the class
design(which is one of the things we try to hide in OOP). You can still
set one (or more) sides to different sizes by using named arguments:

def resize(self, a=None, b=None, c=None):
    self.a = a if a else self.a
    self.b = b if b else self.b
    self.c = c if c else self.c

Now you can call it as

tri.resize(4,5,6)  # set all 3 sides
or
tri.resize()   # change nothing
or
tri.resize(b=7)  # only change size of b
or
tri.resize(a=2,c=8)  #change a and c leave b as is

etc.

User friendly, descriptive and flexible and avoids
exposing internal data that you may decide to change
some day..

> although here in this example , by writing
> tri.a, tri.b & tri.c for setting, the setter function  for a particular
> instance variable is accessed due to property.

Yes, but at the expense of a function call overhead and extra coding.

> writing tri.area gives the area This seems more
> pythonic.

It's not more Pythonic. Creating an area property would be pythonic,
this is just extra layers of code that add no advantage and would
be bad practice in any language.

> What about adopting this practise ?

Please don't. Keep thing as simple as possible (but no more),
to slightly misquote Einstein.

Incidentally Mats mentioned in his post regarding your initial
implementation of resize() that it was identical to init() and
that you could simplify things. I suspect what he had in mind
was that you could call resize from init:

def __init__(self,a,b,c):
   self.resize(a,b,c)

That simplifies the code and avoids potentially harmful code duplication.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos




More information about the Tutor mailing list