【问题标题】:Python3 how to raise a ValueError for a date time object if its not in the right format?如果日期时间对象的格式不正确,Python3 如何引发 ValueError?
【发布时间】:2019-03-29 15:51:27
【问题描述】:

对于一个 uni 项目,我们必须创建一个符合我们已经给出的一些测试的程序。测试使用幻数作为函数的输入。我知道如何让它返回一个日期时间对象。就是不知道怎么报错!

我的代码:


    import datetime
    def time_to_datetime(datetimeSTR):
        datetime_obj = datetime.datetime.strptime(datetimeSTR, '%Y/%m/%d %H:%M')
        if datetimeSTR != datetime.datetime.strptime(datetimeSTR, '%Y/%m/%d %H:%M'):
            raise ValueError('The time must have the format YYYY/MM/DD HH:MM')
        else:
            return datetime_obj

测试代码:


    import datetime
    import os
    import unittest   # Standard unittest framework.

    import utils   # The module implementing JourneyOptions class.


    class TestTimeToDatetime(unittest.TestCase):
        """Tests for the time_to_datetime function."""

        def test_invalid_time_is_rejected(self):
            with self.assertRaises(ValueError) as cm:
                utils.time_to_datetime('2019/06/09 12:60')
            self.assertEqual(
                'The time must have the format YYYY/MM/DD HH:MM',
                str(cm.exception))

        def test_valid_time_yields_a_dattime_object(self):
            d = utils.time_to_datetime('2019/06/09 12:59')
            self.assertTrue(isinstance(d, datetime.datetime))

这些是我得到的结果:

======================================================================

ERROR: test_valid_time_yields_a_dattime_object (__main__.TestTimeToDatetime)

Traceback (most recent call last):
  File "C:/Users/s5115426/Desktop/tests/test_utils.py", line 21, in test_valid_time_yields_a_dattime_object
    d = utils.time_to_datetime('2019/06/09 12:59')
  File "C:\Users\s5115426\Desktop\tests\utils.py", line 25, in time_to_datetime
    raise ValueError('The time must have the format YYYY/MM/DD HH:MM')
ValueError: The time must have the format YYYY/MM/DD HH:MM

======================================================================
FAIL: test_invalid_time_is_rejected (__main__.TestTimeToDatetime)

Traceback (most recent call last):
  File "C:/Users/s5115426/Desktop/tests/test_utils.py", line 18, in test_invalid_time_is_rejected
    str(cm.exception))
AssertionError: 'The time must have the format YYYY/MM/DD HH:MM' != 'unconverted data remains: 0'
- The time must have the format YYYY/MM/DD HH:MM
+ unconverted data remains: 0

任何帮助将不胜感激!

【问题讨论】:

  • 我假设 if datetimeSTR != datetime.datetime.strptime(datetimeSTR, '%Y/%m/%d %H:%M'): 始终为 True,因为 datetime.datetime.strptime 返回的是日期时间,而不是字符串。
  • datetime.strptime() 正在提高 ValueError 由于您之前的输入无效。这就是您检查错误消息的测试失败的原因,因为它返回的错误消息与您期望的不同。 docs.python.org/3.7/library/…

标签: python python-3.x date datetime


【解决方案1】:

您所犯的错误是如果日期字符串与给定格式不匹配,strptime 会引发值错误。例如:

date_str = '2019/06/09 12:60'
datetime_obj = datetime.datetime.strptime(date_str, '%Y/%m/%d %H:%M')
.
.
ValueError: unconverted data remains: 0

datetime_obj 永远不会被设置,因为 strptime 永远不会返回值。

此外,如前所述,您正在比较来自 strptime 的响应与 inout 字符串——这永远不会起作用。

尝试更简单的方法:

import datetime
def time_to_datetime(datetimeSTR):
    datetime_obj = datetime.datetime.strptime(datetimeSTR, '%Y/%m/%d %H:%M')
    return datetime_obj

或者您可以捕获任何异常并重新加注(imo,不好的做法,但可能值得做一下说明。

import datetime
def time_to_datetime(datetimeSTR):
    try:
        datetime_obj = datetime.datetime.strptime(datetimeSTR, '%Y/%m/%d %H:%M')
    except ValueErr as err:
        print(err)
        raise ValueError('The time must have the format YYYY/MM/DD HH:MM')
    else:
        return datetime_obj

通过这种方式,您可以看到 strptime 在您的测试中对各种输入的表现如何,并且您的函数中有错误处理....不过,正如我所指出的,重新引发错误是 (imo) 不好的做法。

【讨论】:

  • 所以如果我要尝试以正确的方式捕获错误,我将如何处理?
  • @Flirps 您可以允许 strptime 引发异常并注意它仍然是一个值错误 - 在 python 命令行上尝试它,您将自己看到。 OTOH,您可以捕获错误并用您自己的消息重新提出它......两者都是有效的方法。就我个人而言,我觉得前者是更好的现实世界实践。上下文管理器中检查异常的断言可以以任何方式工作——但消息会有所不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多