How do I return a new instance of the python class itself dynamically inside it?

4

I am giving a study in Python and for this I am putting together a Python class that I had already done in PHP.

For example, in a given method in PHP I needed to return the same instance of the class dynamically, but without using $this (which refers to the current instance of the object), since I want to apply immutability in this case .

Example:

class Time {

        public function diff(Time $time) {
              $seconds = abs($time->getSeconds() - $this->getSeconds());

              return new static(0, 0, $seconds);
        }
}

That is, a given method returns the instance of the class itself, but not the same instance, but a new instance.

In python I currently have this:

class Time(object):

    __seconds = 0

    def __init__(self, **kw):

        self.set_time(**kw)

    def set_time(self, **kw):

        seconds = (kw.get('hours', 0) * 3600) \
        + (kw.get('minutes', 0) * 60) \
        + kw.get('seconds', 0)

        self.__seconds = seconds

        return self

   def diff(self, other):
      seconds = abs(self.get_seconds() - other.get_seconds())

      #como posso fazer para retornar uma nova instância com 'seconds' aqui?
    
asked by anonymous 18.05.2016 / 20:32

2 answers

3

I ended up finding out how to solve this problem.

Just use the special attribute __class__ of the current class, you can create a new instance.

Example:

 class Time(object):

     def diff(self, other):

        seconds = abs(self.get_seconds() - other.get_seconds());

        return self.__class__(seconds=seconds)

So, if I inherit, in some object, the class Time , it will not be necessary to recreate the diff method, since it already obtains the class name dynamically through __class__

class NewTime(Time):
    pass

a = NewTime(seconds=5)

b = NewTime(seconds=2)

c = a.diff(b)

print (c.__class__) #<class '__main__.NewTime'>
    
18.05.2016 / 21:35
0

If I understood the problem, just return a new instance of the class itself. I've altered some things in your class to run and show the result:

class Time(object):
    def __init__(self, **kw):
        self.__seconds = 0 
        self.set_time(**kw)

    def set_time(self, **kw):
        seconds = (kw.get('hours', 0) * 3600) \
        + (kw.get('minutes', 0) * 60) \
        + kw.get('seconds', 0)
        self.__seconds = seconds
        return self

    def diff(self, other):
        seconds = abs(self.get_seconds() - other.get_seconds())
        return Time(**{'seconds':seconds})

    def get_seconds(self):
        return self.__seconds

x = {'hours':1, 'minutes':2, 'seconds':1}
t = Time(**x)
print t.get_seconds()

x2 = {'hours':1, 'minutes':0, 'seconds':0}
t2 = Time(**x2)
print t2.get_seconds()

t3 = t.diff(t2)
print t3.get_seconds()

Output:

3721
3600
121
    
18.05.2016 / 21:10