使相对复杂的日期时间函数更加pythonic

时间:2016-06-30 20:02:11

标签: python

我正在处理一个函数,该函数返回给定时区和给定频率的特定时间集;一天,一周,一个月。对于任何给定的时区和频率,该函数将返回给定的最后一个完整频率的unixtime小时开始和unixtime小时结束。例如,最后一整天,最后一整天7天或最后一个完整月份。

import calendar
import pytz
import time

from datetime import datetime, timedelta, time

def get_international_dates(timezone, frequency):
    tz = pytz.timezone(timezone)
    today = datetime.now(tz).date()
    midnight = tz.localize(datetime.combine(today, time(0, 0)), is_dst=True)
    last_full_day_midnight = int(midnight.astimezone(pytz.utc).strftime("%s"))
    if frequency == 'd':
        day_end = last_full_day_midnight - 3600
        day_start = last_full_day_midnight - (3600 * 24)
        prev_day_end = day_end - (3600 * 24)
        prev_day_start = day_start - (3600 * 24)
        return {'start': day_start, 'end': day_end, 'prev_start': prev_day_start, 'prev_end': prev_day_end}
    if frequency == 'w':
        week_end = last_full_day_midnight - 3600
        week_start = last_full_day_midnight - (3600 * 24 * 7)
        prev_week_end = week_end - (3600 * 24 * 7)
        prev_week_start = week_start - (3600 * 24 * 7)
        return {'start': week_start, 'end': week_end, 'prev_start': prev_week_start, 'prev_end': prev_week_end}
    if frequency == 'm':
        month_length = calendar.monthrange(today.year, today.month - 1)
        month_end = last_full_day_midnight - 3600
        month_start = last_full_day_midnight - (3600 * 24 * month_length[1])
        prev_month_end = month_end - (3600 * 24 * month_length[1])
        prev_month_start = month_start - (3600 * 24 * month_length[1])
        return {'start': month_start, 'end': month_end, 'prev_start': prev_month_start, 'prev_end': prev_month_end}

这个功能可以正常工作,但它似乎非常混乱和非pythonic。我该怎么做才能使它更干净,简洁和pythonic?

1 个答案:

答案 0 :(得分:1)

使这个更加pythonic可能不是那么容易,因为它只是声明。但是你可以通过以下方式改进你的代码:

  1. 不使用魔术数字。这将确保您的代码是可配置和可扩展的。当然,参数不会因为过去几千年没有变化,但你永远不会知道。存储常数总是一个好习惯。
  2. 使用elif而不是多个ifs,只有一个可能的结果。你无论如何都要回来了,但再次,习惯它是一个好习惯。
  3. 如果您真的想要“更轻”的代码,因为这几乎只是永远不会改变的配置,您可以选择将配置外包到持久性文件(例如xml)的方法。

    您可以做的另一件事是将其转换为builder/factory,以便您可以创建更多动态类型。它将更加封装,但在一天结束时,逻辑几乎保持不变。