2017-06-16 6 views
0

私はcsvテーブルを入力として受け取り、カレンダーイベント(ics)を出力するツールを作っています。配列を引数として書式化してコンソールに書き込む/

def append_to_ics(event, day, file_name=None): 
    output_file = open(file_name, 'a') 
    output_file.write('BEGIN:VEVENT\n') 
    output_file.write('DTSTART;TZID={}:{}T{}00\n'.format(event.TIME_ZONE, day.strftime('%Y%m%d'), event.start_time)) 
    output_file.write('DTEND;TZID={}:{}T{}00\n'.format(event.TIME_ZONE, day.strftime('%Y%m%d'), event.end_time)) 
    output_file.write('SUMMARY:{}\n'.format(event.class_title)) 
    output_file.write('DESCRIPTION: Teacher: {}; Type of class: {}\n'.format(event.teacher, event.class_type)) 
    output_file.write('LOCATION:{}\n'.format(event.location)) 
    output_file.write('TRANSP:OPAQUE\n') 
    output_file.write('END:VEVENT\n\n') 
    output_file.close() 

「イベント」パラメータは次のとおりです。私はイベントのいずれかの出力内容がコンソールに戦略を持っている、またはICSファイルにデータを書き込み、そのファイルに出力を書き込み方法は次のようになり、いくつかの時点で タイトル、教師などのフィールドを持つオブジェクト 'day'はdatetimeオブジェクトで、 'file_name'は明らかに私が書き込んでいるファイルです。 データをコンソールログと同じように出力する方法はまったく同じですが、ファイルのオープン/クローズはなく、output_file()の代わりにprint()があります。

質問です:私は書き込みとコンソール出力のために同じコードを複製する必要はありませんが、私はすべてのフィールドをフォーマット何とかその後、array/tuple/?..'DTSTART;TZID={}:{}T{}00\n'...に合格する方法のまわりで私の頭をラップすることができないようにする方法を簡素化したいですコンソールのファイルライターに送信してください。

私はすでに試した: まず形式イベント上記の方法のように、テーブル内のすべてを保存し、その後、ちょうどfor loopですべてを書く/コンソール。しかし、これは、イベントのコピーをもう一度テーブルとして保存しなければならないので、過度に複雑に見えます。

答えて

2

sys.stdoutは、標準出力(つまり、コンソール)用の「ファイルライクな」オブジェクトです。

出力ストリームのオープン方法とクローズ方法を気にするのは、append_to_icsの仕事ではありません。そのため、機能の外に置くことができます。

また、出力をループオーバーする必要があるため、パフォーマンスと可読性のために、最終的な文字列を変数に格納することもできます。

これは、次のようになります。 輸入SYS

def append_to_ics(event, day, outputs=None): 
    outputs = outputs or [] 
    s = "\n".join([ 
     'BEGIN:VEVENT', 
     'DTSTART;TZID={}:{}T{}00'.format(event.TIME_ZONE, day.strftime('%Y%m%d'), event.start_time), 
     'DTEND;TZID={}:{}T{}00'.format(event.TIME_ZONE, day.strftime('%Y%m%d'), event.end_time), 
     'SUMMARY:{}'.format(event.class_title), 
     'DESCRIPTION: Teacher: {}; Type of class: {}'.format(event.teacher, event.class_type), 
     'LOCATION:{}'.format(event.location), 
     'TRANSP:OPAQUE', 
     'END:VEVENT', 
    ]) 

    for output in outputs: 
     output.write(s) 

# Call like this: 
with open(file_name, 'a') as output_file: 
    append_to_ics(event, day, [sys.stdout, output_file]) 

注意私が正しく、ファイルの開閉を処理するために、コンテキストマネージャを使用しています。

+0

恐ろしく、ありがとうございました!私が理解していないのは、 '出力'なので、 'append_to_ics'の引数として 'sys.stdout'を渡して、 'sys.stdout.write(s)'を呼び出すと 's'をコンソールにしますか? –

+0

'outputs'はファイルのようなオブジェクトのリストです。この引数を使用する必要はありません。この場合、リストは空になり(2行目参照)、どこにも何も書き込まれません。あるいは、あなたの前のコードと同様に、 '[output_file]'(ファイルにのみ書き込む)や '[sys.stdout]'(コンソールでのみ印刷する)などの単一項目でリストを渡すことができます。あるいは、上記のコードのように、任意の数のファイルのようなオブジェクトを複数の場所に書き込むことができます。 – kjaquier

関連する問題