我们通过用不同类型的参数编写相同的方法来实现函数重载

2022-12-05 03:22:20 发布

您现在位置:Python中文网/ 问答频道 /正文

class area:
   def __init__(self):
      self.rad = 0.0
      self.side = 0
      self.length = 0
      self.breadth = 0
      self.ar1 = 0.0
      self.ar2 = 0
      self.ar3 = 0
   def cal(self,r=0.0,s = 0):
      if(r!=None):
         self.rad = r
         self.ar1 = 3.14*self.rad*self.rad
         print(self.ar1)
      elif(s!=None):
         self.side = s
         self.ar2 = self.side*self.side
         print(self.ar2)





obj = area()
obj.cal(7.0)
obj.cal(12)

我们通过使用不同类型的参数编写相同的方法来实现函数重载,但调用时控件进入if部分而不是elif部分。我们希望使用elif部分实现圆的面积和平方的面积,但同时调用这两个参数进入if部分


Tags: selfnoneobj参数ifdefareasidecalprint面积elifradar2ar1
1条回答
网友
1楼 · 发布于 2022-12-05 03:22:20

我认为你的问题是那些r!=Nones!=None。至少这肯定是一个破坏代码的问题;我不确定是不是你要问的那个

这些参数的默认值是0.00。两者都不等于None

  • 如果要检查它们是否非零,可以比较r != 0s != 0
    • …或者r != 0.0
    • …或者not math.isclose(r, 0)
  • 如果你想检查它们是否是真的,None和零都不是真的,但非零的数字只是检查r本身
  • 如果要检查它们是否被遗漏在调用之外,则需要将函数定义中的默认值改为None
    • … 但是你应该检查is not None,而不是!= None

同时,如果同时为这两个传递值,会发生什么?或者两者都没有


另外,如果您希望人们传递s而不传递r,那么唯一的方法就是作为关键字参数(除了通过查看函数定义来查看r的默认值是什么,然后显式传递该值)

所以,也许这些应该只是关键字参数


综上所述,以下是你想要的:

def cal(self, *, r=None, s=None):
    if r is not None:
        raise TypeError('cal() needs either r or s')
    elif r is not None and s is not None:
        raise TypeError('cal() needs only one of r or s')
    elif r is not None:
        self.rad = r
        self.ar1 = 3.14*self.rad*self.rad
        print(self.ar1)
    else:
        self.side = s
        self.ar2 = self.side*self.side
        print(self.ar2)

现在:

>>> obj = area()
>>> obj.cal(7.0)
TypeError: cal() takes 1 positional argument but 2 were given
>>> obj.cal()
TypeError: cal() needs either r or s
>>> obj.cal(r=7.0)
153.86
>>> obj.cal(s=12)
144

但实际上,有一个更简单的方法来完成这一切:

def circle(self, r):
    # do circle stuff
def square(self, s):
    # do square stuff

在定义端和调用端更易于编写和阅读:

>>> obj.circle(7)
153.86
>>> obj.square(12)
144