2016-06-30 6 views
0

私は与えられたタイムゾーンと与えられた頻度に対して特定の時間のセットを返す関数に取り組んでいます。日、週、月。与えられたタイムゾーンと周波数に対して、最後に与えられた完全な周波数のunixtime hour startとunixtime hour endを返します。たとえば、最後の一日、最後の完全な7日、または最後の満月です。比較的複雑なdatetime関数をもっとpythonicにする

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} 

この機能は正常に動作しますが、非常に乱雑で非pythonのようです。これをもっときれいに簡潔にするために私は何をすべきですか?

+2

おそらくそれは[codereview.se]の方がより適しているでしょう – ForceBru

+1

各変換バリアントを取り除くだけで、はっきりと分かります。例えば。 'if frequency == 'd':get_international_daily_dates(...)'等 – MisterMiyagi

答えて

1

これをもっとpythonicにするのは、単なるステートメントなので、おそらく簡単ではありません。しかし、あなたは確かにあなたのコードを改善することができます:

  1. マジックナンバーを使用していません。これにより、コードが構成可能でスケーラブルであることが保証されます。確かに、パラメータは過去数千年もの間は変わらないだろうが、あなたは決して知らない。定数の格納は常に良い習慣です。
  2. 複数のifsの代わりにelifを使用し、結果は1つしかありません。とにかく戻ってきますが、もう一度、それに慣れるのは良い習慣です。

「軽い」コードが本当に必要な場合は、ほとんど変更されない設定なので、構成を永続的なファイル(xmlなど)にアウトソースするアプローチを選択できます。

もう1つのことは、より動的なタイプを作成できるbuilder/factoryにすることです。もっとカプセル化されますが、その日の終わりには、ロジックはほぼ同じままです。

+0

'builder/factory'について説明できますか? – metersk

+1

これらのパターンは、Java/C#などでよく使用されていますが、Pythonではこれほど一般的ではありません。そのアイデアは、そのビルダー・クラスのインスタンス上でメソッドを呼び出すことによって、オブジェクトまたはデータ構造をアセンブルできるクラスを作成することです。これは、オプションのパラメータを持つようなものですが、より安全な型セーフです。単なる提案であり、おそらくこのシナリオで実装しようとする価値はありません。私がすでに述べたように、あなたのコードをより小さなものにするでしょう。私は元の答えのパターンを説明するウィキペディアのページもリンクします。 –

関連する問題