f文字列を使うと変数や式の値をスッキリと書式化できます。が、日付を書式化しているそのf文字列、もっとカンタンに書けるんじゃないですか?
以下のコードは現在時刻をdatetime.datetime.now関数で取得して、f文字列でそれを書式化するものだ。これをもっとカンタンにせよ。
from datetime import datetime
now = datetime.now()
s = f'date: {now.strftime("%Y-%m-%d")}'
お初にお目にかかります。「ヘナチョコPythonistaかわさき」略して「HPかわさき」です。アイコンは自撮りの写真をChatGPTに入力して、「あーでもない。こーでもない」といいながら、Dall-E 3に作ってもらったものです(似ているんですかね。よく分からないなぁ)。
というわけで、今回から「Pythonステップアップクイズ」略して「Pythonクイズ」を担当させていただきます。本連載は、Pythonでプログラミングする際に出会うかもしれないちょっとしたワナや、知っておくといいことなどを題材として皆さんにクイズを解いてもらおうというものです。
クイズの答えの後には解説もあるので、「ん? わかんねぇぞ」とか「もっと詳しく!」といった方はそちらも読んでくださると幸いです。
それでは答えの発表でーす。
以下に正解のコード例を示します。
from datetime import datetime
now = datetime.now()
s = f'date: {now:%Y-%m-%d}'
datetimeクラスのオブジェクトをf文字列で書式化する場合、strftimeメソッドで指定する書式コードをその置換フィールドの書式指定子として記述できます。そのため、置換フィールド内でstrftimeメソッドを呼び出す必要はありません。
「画像だけあればいいじゃん!」と思う方もいらっしゃるでしょうが、画像だけだとコピペですぐに試せないのでテキストでもコードを紹介してみました。
datetimeモジュールのdatetimeクラスにはstrftimeメソッドがあります。これを使うと日付データを文字列として書式化できます。
from datetime import datetime
now = datetime.now()
s = now.strftime("%Y-%m-%d") # yyyy-mm-dd形式の文字列に書式化
また、f文字列を使うと変数の値や式の計算結果を文字列に埋め込めます。
x = 1
s = f'x = {x}' # f'{x=}'でも可(Python 3.8以降)
これらを組み合わせることで、日付データを任意の形で文字列に埋め込めます。これをやっているのが問題文のコードです。
from datetime import datetime
now = datetime.now()
s = f'date: {now.strftime("%Y-%m-%d")}'
しかし、既に述べたように、f文字列の書式指定子にはdatetimeクラス(dateクラス、timeクラス)のstrftimeメソッドで指定可能な書式コードを記述できます。これにより内部的にstrftimeメソッドが呼び出されます。そのおかげで、わざわざ上のような書き方をせずに以下のように書くだけで済むようになっています。
from datetime import datetime
now = datetime.now()
s = f'date: {now:%Y-%m-%d}'
どうしてこんなことが可能かといえば、それはdatetimeクラスでは__format__特殊メソッドをオーバーライドしているからです。興味のある方は以下の【おまけ】も読んでくださいね。
Pythonの特殊メソッドの一つに__format__特殊メソッドがあります。これはその名前から想像できる通り、書式化する際の処理をカスタマイズするのに使用します。datetimeモジュールのdateクラス、datetimeクラス、timeクラスではこの特殊メソッドをオーバーライドして、f文字列やstr.formatメソッドで書式化する際の書式指定子として、各クラスのstrftimeメソッドで指定できる書式コードを記述できるようになっているのです。
書式指定の詳細については「書式指定文字列の文法」などを参照していただくとして、ここでは__format__特殊メソッドをオーバーライドするちょっとした例をご覧いただいて、今回のクイズを終わりにしましょう。
from datetime import datetime
class mydatetime(datetime):
def __format__(self, format_spec):
s = ''
if '%z' in format_spec:
s += 'this is mydatetime: '
format_spec = format_spec.replace('%z', '')
s += super().__format__(format_spec)
return s
now = mydatetime.now()
s = f'{now:%z%Y/%m/%d %H:%M:%S}'
print(s) # this is mydatetime: 2024/11/19 05:00:00
__format__特殊メソッドが呼び出される際には、そのオブジェクトをどのように文字列化するかを指定する書式指定子が渡されます(format_specパラメーター)。上の例では'%z'がそこに含まれていれば、'this is mydatetime: 'という文字列を書式指定された文字列に含めるようにして、それ以外は基底クラスの__formt__メソッドに処理を任せています。
f文字列については「Python入門」の「フォーマット済み文字列」を、文字列の書式化については「文字列の書式指定」を、datetimeクラスについては「解決!Python」の以下の記事を参照してください。
これらをまとめたeBookもダウンロード可能になっているので、ぜひ役立ててくださいね。
Copyright© Digital Advantage Corp. All Rights Reserved.