Should I, and how to, add methods to int in python

2019-02-23 17:33发布

问题:

(This is a learning related question, so any advice in why should I do or not do anything, as well as recommended resources to get these things better, are more than wellcome.)

I'm trying to learn about OOP in python, and have done a simple "Time" class like this:

class Time(object):

    """A time representation."""

    def __init__(self, hours=0, minutes=0, seconds=0):
        self.hours = hours
        self.minutes = minutes
        self.seconds = seconds

    def __int__(self):
        return self.hours * 3600 + self.minutes * 60 + self.seconds

Now, that __int__ method lets me get an int from my "Time" instances that represent the time (but in seconds) when I do int(Time(3, 4, 5)). I find that to be kind of awesome, by the way. But, in order to use this, it would be nice to know how to make an "int" have a new method that returns a "Time" object, so something like 3643.time() could be done.

Why? For various reasons:

  1. Because that way I learn about what for me is like black magic right now. (these underscored things that make things happen... and related stuff)

  2. Because I don't know why I shouldn't. (so tell me please)

I suppose I could do something like the following outside any class:

def time(seconds):
    """Return an HH:MM:SS stamp of "seconds", where "seconds" should be an int."""
    hours, minutes = 0, 0
    if seconds >= 3600:
        hours, seconds = divmod(int, 3600)
    if seconds >= 60:
        minutes, seconds = divmod(int, 60)
    return "{:02d}:{:02d}:{:02d}".format(hours, minutes, seconds)

But that doesn't seem to relate to these objects enough, It doesn't seem that much object oriented... So, I reckon maybe there is a better way to approach this kind of thing.

回答1:

No, you cannot really add methods to int. You could subclass int, and return that from your __int__ method, but that won't help you much, since calling int() on that will still return a regular int.

Your idea of using a regular function to convert back to Time() is right, but it might be nice to make it a classmethod so it's a little more obvious how it relates:

class Time(object):
    @classmethod
    def from_seconds(cls, seconds):
         _hours, _minutes, _seconds = ...
         return cls(_hours, _minutes, _seconds)