【问题标题】:Validating data (mutators) in a class验证类中的数据(修改器)
【发布时间】:2017-05-09 03:29:53
【问题描述】:

如果例如小时大于 23、分钟大于 60 和秒大于 60,我正在尝试拒绝数据(转换为 0),但是我遇到了它不执行任何操作的问题。我不确定我只是没有正确初始化我的 get/set 方法还是什么。

这是我的代码:

class Clock(object):

    def __init__(self, hour, minute, second):
        self.__hour = hour
        self.__minute = minute
        self.__second = second

    def setHour(self, hour):
        self.__hour = hour
        if self.__hour > 23:
            self.__hour = 0

    def getHour(self):
        return self.__hour

    def setMinute(self, minute):
        self.__minute = minute
        if self.__minute > 60:
            self.__minute = 0

    def getMinute(self):
        return self.__minute

    def setSecond(self, second):
        self.__second = second
        if self.__second > 60:
            self.__second = 0

    def getSecond(self):
        return self.__second

    def __str__(self):
        if self.__hour > 11:
            return 'The Time is {}:{}:{} PM'.format(self.__hour, self.__minute, self.__second)
        else:
            return 'The Time is {}:{}:{} AM'.format(self.__hour, self.__minute, self.__second)


stopwatch = Clock(0, 0, 0)
print(stopwatch)
watch = Clock(10, 30, 0)
print(watch)
wallclock = Clock(5, 66, 42)
print(wallclock)

【问题讨论】:

  • 您的代码从不调用您的任何方法。

标签: python python-3.x class oop


【解决方案1】:

您不会检查 __init__ 中的小时/分钟/秒是否超出范围。将您的 __init__ 更新为:

def __init__(self, hour, minute, second):
    self.__hour = hour
    if self.__hour > 23:
        self.__hour = 0

    self.__minute = minute
    if self.__minute > 60:
        self.__minute = 0

    self.__second = second
    if self.__second > 60:
        self.__second = 0

或更好(遵循 DRY - 不要重复自己):

def __init__(self, hour, minute, second):
    self.setHour(hour)
    self.setMinute(minute)
    self.setSecond(second)

正如@brenbarn 所提到的,您还可以调用底部的 setHour、setMinute 和 setSecond 方法来测试它们是否也可以工作:

stopwatch = Clock(0, 0, 0)
stopwatch.setHour(30)
print(stopwatch)
watch = Clock(10, 30, 0)
watch.setMinute(69)
print(watch)
wallclock = Clock(5, 66, 42)
wallclock.setSecond(70)
print(wallclock)

【讨论】:

  • @NickWeseman 当您的意思是调用这些 set 方法时,应该在 __str__ 方法中吗?
  • 不,就在您创建秒表、手表和挂钟时的底部。将其添加到我的答案底部以澄清。
【解决方案2】:

是的,你没有在你的 init 函数中调用你的方法。
我有另一种方法来实现你的想法,只需在你的类中添加一个__setattr__ 函数:

def __setattr__(self, name, value):
    if name in ['__minute', '__second'] and value > 60:
        return None
    if name in ['__hour'] and value > 23:
        return None
    super().__setattr__(name, value)

此函数将检查值是否正确,如果值超出边界,则将值转换为0。这是一个pythonic函数。

【讨论】:

    【解决方案3】:

    如果您使用的是 Python 3,一个更好的解决方案是使用属性(简化为仅几个小时),例如:

    class Clock:
        def __init__(self, hour, minute, second):
            self._hour = self._minute = self._second = None
    
            # Call the properties to apply validation rules
            self.hour = hour
            self.minute = minute
            self.second = second
    
        def __str__(self):
            return 'The Time is {:02}:{:02}:{:02}'.format(self._hour, self._minute, self.second)
    
        @property
        def hour(self):
            return self._hour
    
        @hour.setter
        def hour(self, value):
            self._hour = 0 if value > 23 else value
    
        @property
        def minute(self):
            return self._minute
    
        @minute.setter
        def minute(self, value):
            self._minute = 0 if value > 59 else value
    
        @property
        def second(self):
            return self._second
    
        @second.setter
        def second(self, value):
            self._second = 0 if value > 59 else value
    

    PS 您的代码允许 61 秒和分钟 ;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-03
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-26
      相关资源
      最近更新 更多