Python3 / Classes / OOP / How do you change the eigenvalues ​​of objects using a method?

I am learning to use python. How to think like a computer scientist: Learn python 3.

I study OOP and compiled code to answer a question in a book, but I feel like I had to do something else.

This code has an incremental() value whose purpose is to increase the values ​​of the object. Now, my final solution was to make my method a copy of the initializer method and just add time there.

This seems sloppy:

 class MyTime: def __init__(self, hrs=0, mins=0, secs=0,): """ Create a new MyTime object initialized to hrs, mins, secs. The values of mins and secs may be outside the range 0-59, but the resulting MyTime object will be normalized. """ # calculate total seconds to represent totalsecs = hrs*3600 + mins*60 + secs self.hours = totalsecs // 3600 # split in h, m, s leftoversecs = totalsecs % 3600 self.minutes = leftoversecs // 60 self.seconds = leftoversecs % 60 def incerment(self,t): # increase the time by t amount totalsecs = self.hours * 3600 + self.minutes * 60 + self.seconds + t self.hours = totalsecs // 3600 # split in h, m, s leftoversecs = totalsecs % 3600 self.minutes = leftoversecs // 60 self.seconds = leftoversecs % 60 t1 = MyTime(5,5,5) t2 = MyTime(10,10,10) t3 = MyTime(12,12,12) print('before:',t1) t1.incerment(100) print('after:',t1) 

So how about this?
Is there any way to clear this?

+4
source share
4 answers

It feels like you have to do something else, these are beacuse hours , minutes , seconds properties .

You really don't need these values ​​stored as attributes of your object, you just want to have access to these values ​​when you need to.

A call of something like:

 >>> t1.hours 5 

So rewrite your example with property :

 class MyTime: def __init__(self, hrs=0, mins=0, secs=0): self.totalsecs = hrs*3600 + mins*60 + secs @property def hours(self): return self.totalsecs // 3600 @property def minutes(self): return self._get_leftoversecs() // 60 @property def seconds(self): return self._get_leftoversecs() % 60 def _get_leftoversecs(self): return self.totalsecs % 3600 def increment(self, t): self.totalsecs += t 

Usage example:

 >>> t1 = MyTime(5,5,5) >>> t1.hours 5 >>> t1.hours() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'int' object is not callable >>> t1.seconds 5 >>> t1.totalsecs 18305 >>> t1.increment(10) >>> t1.seconds 15 >>> t1.totalsecs 18315 

I don't know if you noticed, but you no longer need the increment function :

 >>> t1.totalsecs += 10 >>> t1.totalsecs 18325 

I know that property should be a little ahead of what you are doing, but I thought that would be a worthy example.

Edit: Since Lattyware has noticed that there is no need to create a totalsecs property.

To quote his comment: the wonderful thing about Python properties is that you don’t need to turn everything into getters and setters in order to maintain a consistent interface, as in some languages.

In setting up totalsecs may be an advantage in the quality of the property (read-only) only if for some reason you want to hide the internal implementation of MyTime (obviously by reintegrating the increment() method).

+4
source

You can try this:

  # calculate total seconds to represent self.totalsecs = hrs*3600 + mins*60 + secs self.set_times() def incerment(self, t): # increase the time by t amount self.totalsecs = self.hours * 3600 + self.minutes * 60 + self.seconds + t self.set_times() def set_times(self): self.hours = self.totalsecs // 3600 # split in h, m, s leftoversecs = self.totalsecs % 3600 self.minutes = leftoversecs // 60 self.seconds = leftoversecs % 60 
+1
source

The main change is that you should use incerment in __init__ , since your init contains essentially the same code.

0
source

I would probably refuse access to the "totalsecs" in the property, and then use this:

 class MyTime: def __init__(self, hrs=0, mins=0, secs=0,): """ Create a new MyTime object initialized to hrs, mins, secs. The values of mins and secs may be outside the range 0-59, but the resulting MyTime object will be normalized. """ self.totalsecs = hrs*3600 + mins*60 + secs @property def totalsecs(self): return self.hours * 3600 + self.minutes * 60 + self.seconds @totalsecs.setter def totalsecs(self, totalsecs): self.hours = totalsecs // 3600 # split in h, m, s leftoversecs = totalsecs % 3600 self.minutes = leftoversecs // 60 self.seconds = leftoversecs % 60 def increment(self,t): # increase the time by t amount self.totalsecs += t 

Of course, if you do, you no longer need the increment() method. Plus, if later you decide to switch to the Rik Poggi solution and just save the totalsecs value and make hours, minutes, seconds in the properties, and you have minimal changes.

0
source

Source: https://habr.com/ru/post/1397265/


All Articles