如果我的输入有效,如何检查类方法

时间:2015-04-28 21:31:41

标签: python

在这个程序中,我有一个表示一个卷(包含数量和单位)的类。我在运行它时遇到此错误,并且当我在解释器中尝试以下操作时:

class Volume(object):

    def __init__ (self, m = 0, u = "ml"):
        self.__magnitude = m
        self.__units = u

    def is_valid (self): #checks if the volume and units are valid
        if type(self.__magnitude) == int and type(self.__units) == str:
            if self.__units == "ml" or self.__units == "oz":
                if self.__magnitude < 0:
                    return True
                else:
                    return False
            else:
                return False
        else:
            return False

    def __repr__ (self):
        if Volume.is_valid(self):
            return str(self.__magnitude) + " " + str(self.__units) #needs fix    

    def __str__ (self):
        if Volume.is_valid(self):
            return round(self.__repr__(),3) #fix    

    def units (self): #returns the units of the volume
        if Volume.is_valid(self):
            return self.__units

    def magnitude (self): #returns the magnitude of the volume
        if Volume.is_valid(self):
            return self.__magnitude

    def metric (self): #transforms the magnitude into metric system if needed
        if Volume.is_valid(self):
            if self.__units == "ml":
                return self.__units
            elif self.__units == "oz":
                mil = self.__units / 0.033814
                return mil

    def customary (self): #transforms the magnitude into customary if needed
        if Volume.is_valid(self):
            if self.__units == "oz":
                return self.__units
            elif self.__units == "ml":
                ozs = self.__units * 0.033814
                return ozs

    def __add__ (self, v2): #adds to magnitude using an int or another volume
        if Volume.is_valid(self):
            if isinstance(v2, Volume):
                if Volume.is_valid(v2): #check if V2 is valid
                    if self.__units == v2.__units:
                        return Volume(self.__magnitude + v2.__magnitude, 
                                      self.__units)
                    else:
                        if v2.__units == 'ml':
                            v3 = v2.customary()
                            return Volume(self.__magnitude + v3.__magnitude, 
                                          self.__units)
                        elif v2.__units == 'oz':
                            v3 = v2.__units
                            return Volume(self.__magnitude + v3.__magnitude, 
                                          self.__units)

            elif isinstance(v2,(int,float)):
                #create new Volume with same units as self
                v3 = Volume(v2, self.__units)
                return Volume(self.__magnitude + v3.__magnitude, self.__units)

    def __radd__ (self, v2): #adds ability to do i.e. 2 + a
        return self.__add__(v2)

    def __sub__ (self, v2): #same as __add__ but this subtracts
        if Volume.is_valid(self):
            if isinstance(v2, Volume):
                if Volume.is_valid(v2):
                    if self.__units == v2.__units:
                        return Volume(self.__magnitude - v2.__magnitude, 
                                      self.__units)
                    else:
                        if v2.__units == 'ml':
                            v3 = v2.customary()
                            return Volume(self.__magnitude - v3.__magnitude, 
                                          self.__units)
                        elif v2.__units == 'oz':
                            v3 = v2.__units
                            return Volume(self.__magnitude - v3.__magnitude, 
                                          self.__units)
            elif isinstance(v2,(int,float)):
                v3 = Volume(v2, self.__units)
                return Volume(self.__magnitude - v3.__magnitude, self.__units)

    def __rsub__ (self, v2):
        return Volume(v2.__magnitude - self.__magnitude, self.__units)

    def __mult__ (self, v2):#multiplies a volume by an int only (not other vol)
        if Volume.is_valid(self):
            return Volume(self.__magnitude * v2.__magnitude, self.__units)

    def __rmult__ (self, v2):
        return self.__mult__(v2)

    def __eq__ (self, v2): #checks if 2 volumes are equal
        if Volume.is_valid(self):
            if isinstance(v2, Volume):
                if Volume.is_valid(v2):
                    if self.__units == v2.__units:
                        return self.__magnitude == v2.__magnitude
                    else:
                        if v2.__units == 'ml':
                            v3 = v2.customary()
                            return self.__magnitude == v3.__magnitude
                        elif v2.__units == 'oz':
                            v3 = v2.__units
                            return self.__magnitude == v3.__magnitude
            elif isinstance(v2,(int,float)):
                v3 = Volume(v2, self.__units)
                return self.__magnitude == v3.__magnitude

    def __noteq__ (self, v2): #checks if 2 volumes are not equal
        if Volume.is_valid(self):
            if isinstance(v2, Volume):
                if Volume.is_valid(v2):
                    if self.__units == v2.__units:
                        return self.__magnitude != v2.__magnitude
                    else:
                        if v2.__units == 'ml':
                            v3 = v2.customary()
                            return self.__magnitude != v3.__magnitude
                        elif v2.__units == 'oz':
                            v3 = v2.__units
                            return self.__magnitude != v3.__magnitude
            elif isinstance(v2,(int,float)):
                v3 = Volume(v2, self.__units)
                return self.__magnitude != v3.__magnitude

    def __lt__ (self, v2): #checks if 1 volume is < than the other volume
        if Volume.is_valid(self):
            if isinstance(v2, Volume):
                if Volume.is_valid(v2):
                    if self.__units == v2.__units:
                        return self.__magnitude < v2.__magnitude
                    else:
                        if v2.__units == 'ml':
                            v3 = v2.customary()
                            return self.__magnitude < v3.__magnitude
                        elif v2.__units == 'oz':
                            v3 = v2.__units
                            return self.__magnitude < v3.__magnitude
            elif isinstance(v2,(int,float)):
                v3 = Volume(v2, self.__units)
                return self.__magnitude <= v3.__magnitude

    def __gt__ (self, v2): #checks if 1 volume is > than the other volume
        if Volume.is_valid(self):
            if isinstance(v2, Volume):
                if Volume.is_valid(v2):
                    if self.__units == v2.__units:
                        return self.__magnitude > v2.__magnitude
                    else:
                        if v2.__units == 'ml':
                            v3 = v2.customary()
                            return self.__magnitude > v3.__magnitude
                        elif v2.__units == 'oz':
                            v3 = v2.__units
                            return self.__magnitude > v3.__magnitude
            elif isinstance(v2,(int,float)):
                v3 = Volume(v2, self.__units)
                return self.__magnitude > v3.__magnitude
    def __lteq__ (self, v2):#checks if 1 volume is <= to other volume
        if Volume.is_valid(self):
            if isinstance(v2, Volume):
                if Volume.is_valid(v2):
                    if self.__units == v2.__units:
                        return self.__magnitude <= v2.__magnitude
                    else:
                        if v2.__units == 'ml':
                            v3 = v2.customary()
                            return self.__magnitude <= v3.__magnitude
                        elif v2.__units == 'oz':
                            v3 = v2.__units
                            return self.__magnitude <= v3.__magnitude
            elif isinstance(v2,(int,float)):
                v3 = Volume(v2, self.__units)
                return self.__magnitude <= v3.__magnitude

    def __gteq__ (self, v2):#checks if 1 volume is >= to other volume
        if Volume.is_valid(self):
            if isinstance(v2, Volume):
                if Volume.is_valid(v2):
                    if self.__units == v2.__units:
                        return self.__magnitude >= v2.__magnitude
                    else:
                        if v2.__units == 'ml':
                            v3 = v2.customary()
                            return self.__magnitude >= v3.__magnitude
                        elif v2.__units == 'oz':
                            v3 = v2.__units
                            return self.__magnitude >= v3.__magnitude
            elif isinstance(v2,(int,float)):
                v3 = Volume(v2, self.__units)
                return self.__magnitude >= v3.__magnitude

我需要先修复此错误,然后才能检查其他方法是否有效,但我似乎无法找到解决方法。这是我的代码:

RelativeLayout.LayoutParams adViewParams = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.WRAP_CONTENT,
                RelativeLayout.LayoutParams.WRAP_CONTENT);
        adViewParams.addRule(RelativeLayout.CENTER_HORIZONTAL  | RelativeLayout.ALIGN_PARENT_TOP);
        RelativeLayout layout = new RelativeLayout(this);
        layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT));
     AdRequest adRequest = new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR).build();
    AdView adView = new AdView(this);
    adView.setAdSize(AdSize.BANNER);
    adView.setAdUnitId("some id here");
    adView.loadAd(adRequest);
    layout.addView(adView, adViewParams);

1 个答案:

答案 0 :(得分:2)

def __repr__ (self):
    if Volume.is_valid(self):
        return str(self.__magnitude) + " " + str(self.__units) #needs fix 

在此代码中,如果测试为False,则该函数不会返回任何内容(也就是None),因为您没有else关闭。你在不同的方法中有相同的反模式。之一:

  • 添加else子句以返回合理的值;
  • (可能更好)在无效对象上调用方法时引发异常;
  • 终于,正如@malfunctionning在评论中提到的那样,通常认为在每个方法调用上验证对象都是错误的样式。根据您的用例,您应该在构造函数中验证您的参数,并最终在此时引发异常。

关于Volume(10, "ml") - AFAICT,这将根据您的is_valid方法 验证:

def is_valid (self): #checks if the volume and units are valid
    if type(self.__magnitude) == int and type(self.__units) == str:
        if self.__units == "ml" or self.__units == "oz":
            if self.__magnitude < 0:
                return True
            else:
                return False
        else:
            return False
    else:
        return False

该方法返回True的唯一方法是以"oz""ml"为单位,为负幅度(self.__magnitude < 0 )。

根据我的理解,你的验证逻辑应该是这样的:

def is_valid (self): #checks if the volume and units are valid
    return (self.__units == "ml" or self.__units == "oz") and \
            self.__magnitude >= 0;

总之,您不需要调用is_valid作为类方法:

 if Volume.is_valid(self):
      ...

从我看到的,这是一个正确的实例方法,应该像这样调用:

 if self.is_valid():
     ...