Python 大脑超载了,我怎么能像蟒蛇一样这么做呢?

Python 大脑超载了,我怎么能像蟒蛇一样这么做呢?,python,Python,我知道我不能在python中重载函数,而且我似乎不能用python来获得我想要的行为 例如: class Hop(object): def __init__(self, variety, aa, qty, time): self.variety = variety self.aa = aa self.qty = qty self.time = time class HopBill(object): hop_list = [] d

我知道我不能在python中重载函数,而且我似乎不能用python来获得我想要的行为

例如:

class Hop(object):
   def __init__(self, variety, aa, qty, time):
      self.variety = variety
      self.aa = aa
      self.qty = qty
      self.time = time

class HopBill(object):
   hop_list = []
   def add(self, hop):
      self.hop_list.append(hop)
   # Where I would put an overloaded function?
   def add(self, variety, aa, qty, time):
      self.hop_list.append(Hop(variety, aa, qty, time))
我并不热衷于只使用KWD,只添加一堆逻辑来解码函数接收到的输入

我觉得有一种更好的方法可以解决这个问题,有没有人对如何采取更具python风格的方法有什么建议


谢谢

您可以在Spam类的方法中动态创建一个eggs实例

这应该可以解决问题

def add(self, variety, aa, qty, time):
    new = Hop(variety, aa, qty, time)
    self.hop_list.append(new)
这里有一个方法:

class HopBill(object):
    def __init__(self):
        self.hop_list = []
    def add(self, hop_or_variety, aa=None, qty=None, time=None):
        if isinstance(hop_or_variety, Hop):
            assert aa is None, qty is None, time is None
            self.hop_list.append(hop_or_variety)
        else:
            self.hop_list.append(Hop(hop_or_variety, aa, qty, time))
还请注意,我在
\uuuu init\uuuu
中定义了
hop\u列表
,而不是类定义,否则所有
HopBill
将共享相同的
hop\u列表
这里有一种可能性:

class HopBill(object):
   hop_list = []
   def add(self, hop=None, variety=None, aa=None, qty=None, time=None):
      if hop:
         self.hop_list.append(hop)
      else:
         self.hop_list.append(Hop(variety, aa, qty, time))
你会这样使用它:

hb = HopBill()
hb.add(Hop(1, 2, 3, 4))
hb.add(variety=5, aa=6, qty=7, time=8)

只需要两种方法。Init hop_列表在uuu Init_uuuuu中,或HopBill的实例将共享该列表:

class HopBill(object):
   def __init__(self):
       self.hop_list = []
   def add(self, hop):
      self.hop_list.append(hop)
   def addnew(self, variety, aa, qty, time):
      hop = Hop(variety, aa, qty, time)
      self.add(hop)

我个人赞成马克·托洛宁的回答,但有一种可能性我还没有提到:

class HopBill(object):
   hop_list = []
   def add(self, *params ):
       if len(params)==1 and type(params[0]) == Hop:
           self.hop_list.append( params[0] )
       else:
           self.hop_list.append( Hop(*params) )
这样做的好处是,您可以根据预期用途传递1或4个参数。有一些缺点:

  • 如果您没有传递一个跃点对象或四个参数,则会在
    add
    函数中发现错误,该函数会抱怨您没有提供
    Hop.\uuuu init\uu
    足够(或太多)的参数。在这一点上,真正的问题可能并不明显
  • 调用方必须知道函数确实需要一个或四个参数,以及这些选项的含义
  • 如果您想支持传入的Hop的子类,那么它会变得有点棘手
马克·托洛宁的回答解决了所有这些问题,而且(以我的拙见)更像是蟒蛇。从“导入此项”中可以看出:“显式优于隐式。简单优于复杂……面对歧义,拒绝猜测的诱惑。”


除非出于某种原因,您必须使用相同的名称才能调用,否则我建议您重新调整思路,将重载放在一边。

如果没有代码示例,这几乎是不可理解的。除此之外,您谈论的是重载,而不是重写。重写将是重新定义一个完全替换(但可能会调用)以前定义的方法。他希望有一个函数可以接受一个Egg,或者根据构造函数的参数创建一个新Egg。对不起,这是我的第一篇文章。更新为使用代码示例并使用正确的术语看起来我不知道如何放入代码段,在我发布之前,间距看起来不错。我如何修复它?如果我这样做,我就失去了懒洋洋地添加Hop实例的能力。我想一个方法,要么通过跳,或(品种,aa,数量,时间)取决于方便。我意识到我不能超载,我想知道是否有更好的方法来解决这个问题。在这种情况下,蟒蛇的方法是做两个功能,就像马克·托洛宁所说的。谢谢!我想这就是我所追求的。我不认为这是一种“更具Python风格的方法”,正如OP所要求的那样。+1是迄今为止最干净的答案,唯一没有笨重界面的答案。请注意,
addnew
使用
self.add
而不是复制
self.add
+1所有重载是选择要调用的几个函数之一的另一种方法。只需给函数取不同的名称,您就可以使用通常的方法来选择要调用的函数(名称),以获得完全相同的效果。@Ben:它不会给您相同的效果。如果需要在函数名中输入参数的类型,那么为函数参数使用duck类型有什么意义?有太多的类具有“重载”方法,如
addTree()
addNode()
addList()
,这些方法有效地阻止了您获得duck类型的好处。@AndréCaron duck类型与使用相同名称定义具有不同签名的多个函数非常不同。Duck类型只是依赖于一个(最好是窄的)接口,而不是任何特定的类型;因此,如果您可以使用相同的界面处理列表、树或节点,那么您只需使用该界面,即可自动支持该界面的任何其他功能。如果您不能用同一个界面支持它们,那么使用
isinstance
检查您所拥有的“手动重载”并不能提供Duck键入的所有好处。@Ben:我知道它们是不同的。我说过,不支持同名重载会降低duck类型的适用性。在本例中,您可以将“lazy
Hop
creation”抽象为包含组件的元组或Hop实例本身,但您不能这样做,因为Python不支持重载。在这种情况下,客户机代码无法执行此抽象,因为它需要对函数名中使用的形式进行编码。因此,您不会得到与重载相同的效果。