Emacsのrun-pythonについての理解を深める
run-pythonは、Emacs上でPythonのインタプリタを起動する。関数はlisp/progmodes/python.el.gzで定義されている。引数には、cmd、dedicated、showを渡す事ができる。
起動コマンドには (python-shell-calculate-command)
が返した文字列が使われる。この関数は、 python-shell-interpreter
と python-shell-interpreter-args
からコマンド文字列を組み立てる。
という事は python-shell-interpreter
を設定するコマンドを用意すれば、venv内のPythonを使って起動できる。そこで次のような実装を追加してみた。
(defvar python-venv-directory "~/.cache/python-venvs")
(defun python-venv-set-python (venv-directory)
(interactive (list (read-directory-name
"venv dir: " python-venv-directory)))
(setq python-shell-interpreter
(format "%s/bin/python" venv-directory)))
pytzでタイムゾーンオブジェクトを作る
import pytz
pytz.timezone("Asia/Tokyo")
pytz.timezoneは内部で pytz.tzfile.build_tzinfo()
を呼び出す。この関数は、タイムゾーン情報のファイルを読み出し、ZoneInfoオブジェクトを生成して返す。
タイムゾーン情報のファイルは、 pytz/zoneinfo/
ディレクトリ配下に保持している。このファイルは決めらてた形式のバイナリファイルとなっており、それをstructモジュールを使って読み出している。pytz.tzfile.build_tzinfo()は、その読み出しのためのフォーマット文字列の組み立ても行っている。
ヘッダーのフォーマットは >4s c 15x 6l
、サイズは44バイトだ。データのフォーマットは >9l 9B lBBlBBlBBlBB 12s
、サイズは81バイトだ。これ、何のフォーマットなのだろう。
最終的に以下のようにクラスを作成し、それをインスタンス化している。
cls = type(zone, (DstTzInfo,), {...})
return cls()
おそらく時刻情報が増えた時に対応するためなのだろうけれど、なぜこんなに面倒な実装にしたのだろうか。機会があれば、なぜこうしたのか聞いてみたい。
<DstTzInfo 'Asia/Tokyo' LMT+9:19:00 STD>
この LMT
は、Local Mean Timeの略で地方平均時の事だ。
https://ja.wikipedia.org/wiki/%E5%9C%B0%E6%96%B9%E5%B9%B3%E5%9D%87%E6%99%82
実際に使いたいのは、 JST
でこれは日本標準時だ。この二つは異なる時刻系であり、その変換を間違った方法で行うために、時間のズレが生じてしまうようだ。
時刻系についても勉強してみたいけれど、今回はあまり深追いしないでおく。
https://ja.wikipedia.org/wiki/%E6%99%82%E5%88%BB%E7%B3%BB
datetime.datetimeオブジェクトのastimezone()を使用する場合、内部ではreplaceを使っている。
Pythonでは、時刻情報にタイムゾーン情報がないものと、あるものがあり、ないものをナイーブ、あるものをアウェアと呼び区別する。その時刻情報がアウェアである条件は公式のドキュメント「」に明記されている。 https://docs.python.org/ja/3/library/datetime.html#determining-if-an-object-is-aware-or-naive
そこには、こうある。
d.tzinfo
がNone
でないd.tzinfo.utcoffset(d)
がNone
を返さないこれを確認してみよう。
>>> naive = datetime.datetime.now() >>> naive.tzinfo >>> tz_jp = pytz.timezone("Asia/Tokyo") >>> tz_jp <DstTzInfo 'Asia/Tokyo' LMT+9:19:00 STD> >>> aware = naive.astimezone(tz_jp) >>> aware datetime.datetime(2024, 9, 4, 19, 32, 59, 128833, tzinfo=<DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD>) >>> aware.tzinfo <DstTzInfo 'Asia/Tokyo' JST+9:00:00 STD> >>> aware.tzinfo.utcoffset(aware) datetime.timedelta(seconds=32400) >>> aware.tzinfo.utcoffset(naive) datetime.timedelta(seconds=32400)
pytz.timezone("Asia/Tokyo")
で取得したタイムゾーンは LMT+9:19:00
となっていた。しかし、 naive.astimezone(tz_jp)
でタイムゾーン情報を追加したawareオブジェクトの属性として付いているタイムゾーン情報は JST+9:00:00
となっていた。この変換がどこで行なわれているのか全く分からないけれど、このあたりがズレの原因だろう。
pytzは、過去に何度かあったタイムゾーンの取り扱いの変更や、夏時間の情報などを全て記録しているため、このズレが起きるのだが、僕はこの「過去に何度かあったタイムゾーンの取り扱いの変更」の部分を調べたいのだろう。あのバイナリファイルにあるのかもしれないが、なかなか見えてこない。
Emacsでバックアップファイルを作成しないようにする
(setq make-backup-files nil)
記録できなかった事を引き継ぐ
(注意: この文章はChatGPTによって生成した)
僕たちは日々、無数の思いや経験を積み重ねて生きている。しかし、作業という名の思い出をすべて完璧にこなし、記録していく事はは難しい。それでも、その一つ一つが僕たちの成長や未来の自分へのメッセージとなり得る。だから、それらを手元に置いておきたいと思った。
技術は進化し、僕たちは多くのものをデジタルに記録する。その中でも、リビジョンを管理するツールは強力だ。そして、今はGitが主流と言える。開発者にとっては自分や他人の手によるコードの変遷を追跡し理解する助けとなるし、開発者でなくとも利用する価値はある。
テキストなど記録できるものは、全てGitコミットするという習慣をつけることが重要だ。それはコードだけでなく、アイデアやメモ、試行錯誤の過程を含むものもそうだ。このようにして、僕たちは過去の自分との対話を深め、さらに未来の自分に対する贈り物として記録を残す事ができる。
日常生活や仕事の中で、どんなに小さな事でも「今日やった事」を記録する習慣を持つことは非常に有益である。これらの記録は、記事のディレクトリにまとめることで、過去の自分が経験したことを俯瞰的に見ることができる。これらを実践し、昨日の自分が未来の自分に託した思いを引き継ぎ、堅実な一歩を踏み出せるようにしたい。記録の積み重ねが自分自身の成長の架け橋となり、未来へと続いていくのである。
記録、整理、フィードバックのプロセスを日常的に取り入れることで、僕たちは過去と未来の自分をつなぐことができる。このプロセスは、技術だけでなく、個々の成長にもつながる。記録できなかった思い出や経験も、適切な形で未来へと引き連れていくことができるのである 。