Pythonやそのライブラリを含む他の要素においても、バージョンアップが行われるたびに、これまでの書き方が非推奨とされるケースが相当あります。ただし、インターネット上には古いコードや非推奨の情報が存在しています。それが非推奨であるということを知らない場合には、新しい書き方があるにもかかわらず古い書き方を使用してしまうケースが考えられます。
「この書き方は何だ?見たことないぞ」と思って調査してみると、現在では非推奨になった昔ながらの書き方だったりすることがあります。時間を費やして調査した結果、それが非推奨だったりすると困るわけです。ムダな時間を省くためにも、そのような「現在は使えない、または将来的に使えなくなる(非推奨)」の書き方についてメモします。
とはいえ、気付いた時に追記する予定ですので、増えすぎることはないでしょう。
%を使った文字列の書式設定文字列のフォーマットを定義する際、format()やf文字列を使った記法が現在の主流です。ただ、C言語のprintf()に準拠したような演算子を使った記法で表現する方法もあります。
%name = "山田"
age = 30
print("私の名前は%sで、%d歳です。" % (name, age))name = "山田"
age = 30
print(f"私の名前は{name}で、{age}歳です。")str.format()name = "山田"
age = 30
print("私の名前は{}で、{}歳です。".format(name, age))C言語のprintf()では、任意の文字列において「値を出力する位置にどんな型で出力するか」をパーセント付の識別子で表現します。%sだった場合、文字列を指定された箇所に出力する、といった具合です。この記法がPythonでも使えます。
ただ、「せっかく動的型付け言語なのに、文字列編集をするときに型を気にしないといけないのは面倒だぜ!」と思ったのかはわかりませんが、前述のとおりf-stringsが主流だと思います。こっちは読みやすく、式の評価もサポートしているため、f"結果: {2 * 3}"のように直接計算結果を埋め込むことができます。format()関数も一応見かけますね、%ほどは廃れていない印象。
f = open("example.txt", "r")
content = f.read()
f.close() # 忘れると問題が発生する可能性ありwith open("example.txt", "r") as f:
content = f.read()
# 自動的にクローズされるwithはそのブロックを抜けるときに、closeメソッドを勝手に呼び出してクローズしてくれるので、クローズ忘れがなくなりますしコードも読みやすくなります。しかし、withには更なる利点があります。
ファイルオブジェクトを扱うときに with キーワードを使うのは良い習慣です。 その利点は、処理中に例外が発生しても必ず最後にファイルをちゃんと閉じることです。
オフィシャルのドキュメントに書いてある上記の点だけを鑑みても、withを利用するほうが良いと判断できます。
pd.nppd.np経由でNumPy関数にアクセスimport pandas as pd
result = pd.np.sqrt(4) # 非推奨import pandas as pd
import numpy as np
result = np.sqrt(4) # 推奨pandasをインポートすると、同時にNumPyもインポートされます。このとき、pd.npという書き方をすることで明示的にNumPyをインポートしていなくてもNumPyが持つ機能にアクセスできるようになります。import numpyを書かなくてもいいという、メリット?うーん、メリットかなぁこれ。
ただ、NumPyの関数などを使うならちゃんとインポートした方がコードの保守性が高いと思われたのか、現在では非推奨です。そのうち、この機能が削除されると思います。
dict.has_key()d = {"key": "value"}
if d.has_key("key"): # Python 3では削除済み
print("キーが存在します")in演算子d = {"key": "value"}
if "key" in d:
print("キーが存在します")さすがに古すぎる話題ですが、Python2には辞書に任意のキーが存在するかをチェックするhas_key()が存在していました。Python3系ではこいつは削除されており、そもそもエラーになります。現在はinを利用します。
xrangeはもうないぞrangeとxrange# Python 2
for i in range(1000000): # メモリを大量に消費
pass
for i in xrange(1000000): # メモリ効率が良い
passrange(Python 3)Python 3では、range()はイテレータになり、xrange()は削除されました。
# Python 3
for i in range(1000000): # メモリ効率が良い
passPython2では、range()はリストを生成し、xrange()はイテレータを生成していました。Python3ではxrange()がなくなり、range()に統合されました。
__init__、__repr__などの実装class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"Person(name={self.name}, age={self.age})"
def __eq__(self, other):
if not isinstance(other, Person):
return False
return self.name == other.name and self.age == other.age@dataclassデコレータの使用 (Python 3.7以降)from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
# __init__, __repr__, __eq__などが自動的に生成されるdataclassデコレータを使えば、__init__()で引数をわざわざインスタンス変数に代入したり、__eq__()を手で書く必要がなくなりました。Python3.7以降で利用できます。
axismean()などの関数にaxisパラメータなしで使用mean_value = df.mean() # 警告なしだが、axis=0を暗黙的に使用厳密に「古い方法」かまでははっきりしなかったものの、こういう書き方は多くはないものの見かける。確かに省略できるけども、パッと見で「どっち?」ってなるんだよなぁ。
axisを指定# 列ごとの平均
mean_value = df.mean(axis=0)
# 行ごとの平均
mean_value = df.mean(axis=1)単純にこっちの書き方が省略されるよりわかりやすいので、axisは省略できるとしても書いておいたほうがいいと思います。