LoginSignup
7
3

More than 1 year has passed since last update.

[Python] __repr__メソッドをカスタマイズする

Posted at

インスタンスのprint表示をカスタマイズしたい

自分でクラスを作る。

class Dummy():
    def __init__(self, argument, *args, **kwargs):
        # インスタンス変数
        self.argument = argument
        self.arg1 = args[0]

    def fit(self):
        pass

    def predict(self):
        pass

これをprintすると、、

print(instance)

# <__main__.Dummy object at 0x7ff7177d8990>

ななな、なんじゃこら。

こんなふうに引数を表示したい。。。

from sklearn.ensemble import RandomForestClassifier

clf = RandomForestClassifier(max_depth=2, random_state=0)
print(clf)

# RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,
#                        criterion='gini', max_depth=2, max_features='auto',
#                        max_leaf_nodes=None, max_samples=None,
#                        min_impurity_decrease=0.0, min_impurity_split=None,
#                        min_samples_leaf=1, min_samples_split=2,
#                        min_weight_fraction_leaf=0.0, n_estimators=100,
#                        n_jobs=None, oob_score=False, random_state=0, verbose=0,
#                        warm_start=False)

Scikit-learn likeのAPIをつくるなら、sklearn.baseの配下のクラス(base.ClassifierMixinbase.RegressorMixin等)を継承すればよいが、自分でカスタムしたいという人もおられるだろう。そんなときは、特殊メソッドの__repr__を書き換えれば良い。

__repr__はオブジェクトの公式な文字列表現である。公式には、この表現を見れば元のオブジェクトを再生成できるように表示すべし、と書いてある。まさにscikit-learnのようにすべしということである。

class State:
    _defaults = {"A": 1, "B": 2}

    def __init__(self, argument, *args, **kwargs):
        # インスタンス変数
        self.argument = argument
        self.arg1 = args[0]
        # クラス変数
        self.__dict__.update(self._defaults)
        # キーワード引数
        self.__dict__.update(kwargs)

    def __repr__(self):
        kws = [f"{key}={value!r}" for key, value in self.__dict__.items()]
        return "{}({})".format(type(self).__name__, ", ".join(kws))

    def __eq__(self, other):
        return self.__dict__ == other.__dict__  # you might want to add some type checking here
instance1 = State('a', 'b')
print(instance1)

# State(argument='a', arg1='b', A=1, B=2)

インスタンス変数ではないが、表示したいものはself.__dict__に辞書で登録する。

インスタンス変数に後から追加したものも表示される。

instance1.name = 'name'
print(instance1)

# State(argument='a', arg1='b', A=1, B=2, name='name')

上の例では__eq__メソッドも実装してあるので、インスタンスの比較は引数の比較になるぞ。

instance1 = State('a', 'b')
instance2 = State('a', 'b')
instance3 = State('c', 'd')

print(instance1 == instance2)  # True
print(instance1 == instance3)  # False

参考

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3