【问题标题】:Should I, and how to, add methods to int in python?我应该以及如何在 python 中向 int 添加方法?
【发布时间】:2013-09-20 18:48:51
【问题描述】:

(这是一个与学习相关的问题,所以任何关于我为什么应该做或不做任何事情的建议,以及让这些事情变得更好的推荐资源,都非常受欢迎。)

我正在尝试在 python 中学习 OOP,并且已经完成了一个简单的“时间”类,如下所示:

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

现在,那个 __int__ 方法让我可以从我的“时间”实例中获取一个 int,它表示我执行 int(Time(3, 4, 5)) 时的时间(但以秒为单位) .顺便说一句,我觉得这太棒了。但是,为了使用它,最好知道如何让“int”有一个返回“Time”对象的新方法,这样就可以做到3643.time()

为什么? 由于各种原因:

  1. 因为这样我现在才知道什么对我来说就像黑魔法。 (这些使事情发生的强调的事情......以及相关的事情)

  2. 因为我不知道为什么不应该这样做。 (所以请告诉我)

我想我可以在任何课程之外做以下事情:

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)

但这似乎与这些对象并没有足够的关系,似乎没有那么多面向对象......所以,我认为也许有更好的方法来处理这种事情。

【问题讨论】:

  • 在我看来,除非对象表示一个普通的数字量,否则提供__int__ 方法可能是个坏主意。 (在您的示例中,我认为在 Time 上调用 int() 以获得自午夜以来的秒数的语义令人困惑)。
  • 你不应该也不能(至少不作弊)。不包括命名空间的原因(如果另一个模块也添加了int.time 方法会发生什么?),关注点分离(为什么 int 应该知道如何将自己转换为您的类?),这是不必要的事实,不明显的10 .time(),你必须写10 .time()而不是10.time(),因为词法分析器的怪癖,任何可能的实现的一般hackiness(不可靠性,晦涩难懂),以及Rubyist这样做的事实;-)
  • 另外,没有 OO 感觉的东西不一定是坏事。 Python 允许您混合和匹配 OOP 和良好的旧程序编程,以避免迷失在 kingdom of nouns 中。
  • 哦,还有一件事:如果Time 课程不仅仅是一个示例或用于学习,那就别管它了。时间是困难的,而现有的解决方案(例如datetime 模块)几乎在任何意义上都更好。
  • @delnan 谢谢,这是为了学习。你给了我我真正想要的东西,让我看到的概念。

标签: python class oop methods int


【解决方案1】:

不,您不能真正向 int 添加方法。您可以子类化 int,并从您的 __int__ 方法中返回它,但这对您没有多大帮助,因为在其上调用 int() 仍将返回常规 int。

您使用常规函数转换回Time() 的想法是正确的,但将其设为类方法可能会更好,这样它的关系就更明显了:

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

【讨论】:

  • 为了记录,这通常称为命名构造函数
  • 你可能想保留Time(object):,因为我们现在都在使用新的样式类:)
  • 另一种方法是编写您的主构造函数以获取多种输入。
  • 好的,谢谢。这很有趣。我会尽量熟悉它。
  • 好吧,我猜__int__ 表示 ferhtgoldaraz 使用的是 python 3。是的,在 python 2 中,此方法称为 __index__,并确保在这些情况下继承自 object
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-14
  • 2016-11-16
相关资源
最近更新 更多