まとめへのリンク
はじめに
Pythonの勉強をするために、acopyという群知能ライブラリを写経していました。
acopyでは、多くのPythonの面白い文法・イディオムが使われており、その中でも便利だなぁというのをまとめています。
今回は、vars
という組み込み関数について見ていきます。
varsとは?
pythonには、組み込み関数がいくつかありますが、そのうちの一つがvars
という関数です。
vars(x)
は、オブジェクト$x$の__dic__
属性を辞書として返します。
__dic__
とは?
__dic__
とは、モジュールやクラス・インスタンスのオブジェクトの、dict属性のことです。
dict属性には、オブジェクトに設定されているすべてのプロパティの名前と対応付けられている値が入っています。
具体例
varsが、__dic__
属性を返しているのを簡単なコードで見てみます。
class A:
def __init__(self, x, y):
self.x = x
self.y = y
def f():
x = 50
print(vars())
a = A(10, 20)
'''
{'x': 10, 'y': 20}
'''
print(vars(a))
'''
{'x': 50}
'''
f()
クラスAのオブジェクトaにvars
を使用してみます。
すると、クラスAのオブジェクトaに設定されている__dic__
属性、つまりaのすべてのインスタンス情報を辞書で取得できます。
また、関数内でも関数内のローカルシンボルテーブルが定義されるため、何もvarsに指定しなければ、そのローカルシンボルテーブルの__dic__
を返します。よって、xの辞書を返します。
このように、varsによって、__dic__
属性を習得することができます。
活用法: オブジェクトをすべて渡す
varsを利用することで、例えばクラスのインスタンスのすべての情報を、他のクラス・メソッドにわたすことができます。
アンパックという機能と組み合わすことができるためです。
例えば、以下のようなコードを見てみます。
class KeywordPrinter:
@staticmethod
def printer(**kwargs):
text_arr = [f'(key = {key}, value = {kwargs[key]})' for key in kwargs.keys()]
return ', '.join(text_arr)
class A:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return self.__class__.__name__ + KeywordPrinter.printer(**vars(self))
'''
A(key = x, value = 10), (key = y, value = 20)
'''
a = A(10, 20)
print(a)
まず、KeywordPrinterという辞書をすべて文字列に直すクラスを定義します。
また、クラスAに__repr__
属性のメソッドを定義し、printで任意の文字列を出力できるようにし、よりシンプルにデバッグできる状態を目指します。
ここで、__repr__
内で、KeywordPrinterに**vars(self)
というものを渡しました。
まず、vars(self)
でインスタンスaのプロパティ辞書情報を取得します。
そして、それをアンパックしてPrinterに渡すことで、辞書を文字列として見やすく返してくれます。
これは極端な例で、あまり使用するべきではありませんが、実際のコーディングで、他のメソッドやクラス・関数に「ローカル変数をぱぱっと渡したいな〜」という状況があります。
このとき、**vars(self)
などを使用すると、うまくコーディング量を下げることができるかもしれません。
自分ももっと勉強していこうと思います。