【问题标题】:"Method overloading" in pythonpython中的“方法重载”
【发布时间】:2011-07-06 23:35:36
【问题描述】:

我认为这个概念叫做重载。 现在我正在编写一个将提供 getter 和 setter 方法的类,并且被困在一个设计问题上。

这两种方法都是单行的,只需设置一个值或返回一个值。

def set_number(self, num): self.count = 数量 def get_number(self): 返回 self.count

通过做一些基本上将两种方法合二为一的事情,然后根据是否提供 num 参数来决定应该执行哪一行,是否会更好地节省空间并让类“看起来”更小?

或者我应该坚持清楚并将它们分开吗?有些人认为单独保留所有这些单线是“浪费空间”,而另一些人则不同意,更愿意将它们分开。

有什么理由让我选择其中一个?

【问题讨论】:

  • 使用@property。它将为您简化这一过程并消除所有的麻烦。

标签: python overloading


【解决方案1】:

在 Python 中,您应该完全不使用 getter 和 setter。而是直接引用 count 属性,例如print instance.countinstance.count = 5

在其他语言中,getter 和 setter 的意义在于封装和面向未来,以防您需要向 getter 或 setter 添加逻辑。在 Python 中,您可以稍后使用 property 来完成此操作,这不会破坏您现有的 API。

@property
def number(self):
     # do extra logic if necessary
    return self.count

属性也可以有设置器 - 请参阅:http://docs.python.org/library/functions.html#property

Python 不是 Java。 =)

额外的阅读材料:

【讨论】:

  • 哦,这很酷。如果我以后真的需要,我可以添加设置器。
  • 通读关于 tomayko 和 cmets 的文章,似乎有几个原因表明它不是最佳选择,但我不确定它们是否指的是同一件事。
  • @Keikoku:想引用细节吗?我所看到的要么是非常主观的陈述,源于没有正确阅读文章,要么在后来的评论中被消除了。
  • @delnan,应该是 #6 和 #17。似乎有些人不喜欢让它看起来像是在直接访问属性?
  • @Keikoku:嗯,#6 是无效的恕我直言,因为 getter/setter 方法的更改也可以开始引发异常等。或者(最后几句话似乎是这样说的),海报是'不是特别反对属性,还有 getter/setter 和其他一切。同样无效的恕我直言,因为他未能命名一种替代方法来验证输入,该输入神奇地适用于每个客户的代码。至于#17,请看下面的cmets。
【解决方案2】:

通常在 python 中,使用显式 getter/setter 方法是非常糟糕的风格。只需执行以下操作:

In [1]: class Foo(object):
   ...:     def __init__(self):
   ...:         self.num = 1
   ...:         
   ...:         
In [2]: f = Foo()
In [3]: f.num
Out[3]: 1
In [4]: f.num = 2
In [5]: f.num
Out[5]: 2

如果您确实需要逻辑,您可以在以后使用properties 保留相同的 API。请注意下面如何在保留相同界面的同时仍添加功能。

In [8]: class Foo(object):
   ...:     def __init__(self):
   ...:         self._num = 1
   ...:     @property
   ...:     def num(self):
   ...:         return self._num
   ...:     @num.setter
   ...:     def num(self, num):
   ...:         if num < 0:
   ...:             raise ValueError("Your Foo would be too small!")
   ...:         self._num = num
   ...:         
   ...:         
In [10]: f = Foo()
In [11]: f.num
Out[11]: 1
In [12]: f.num = 2
In [13]: f.num
Out[13]: 2
In [14]: f.num = -1
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)

/home/Daenyth/<ipython console> in <module>()

/home/Daenyth/<ipython console> in num(self, num)

ValueError: Your Foo would be too small!

关于“重载”——该术语在这里不适用。这是通过更改对象上这些方法的定义来更改 +== 等运算符行为的术语。你可以通过__cmp__, __add__, and so on.在python中做一些重载

【讨论】:

  • 那是“压倒一切”。重载意味着两个方法名称相同但签名不同。这是你在 Python 中无法做到的。
  • @FogleBird;呃,你是对的。我弄混了不过,您可以通过__cmp__ 等进行一些重载。
  • @FogleBird:当然,你不需要,因为你可以使用(*args, **kwargs),然后根据你传递的参数/多少来表现不同。
  • @FogleBird:这不是叫“多次派送”吗?
【解决方案3】:

为了代码的可读性和可维护性,我会将其保留为两个单独的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-08
    • 2019-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    相关资源
    最近更新 更多