Python Tech

[Python]インスタンス変数に文字列を指定してアクセスする方法

Pythonのインスタンス変数にアクセスするとき、変数名を文字列で指定して取得したいときがあります。

この記事ではそんな実装をPythonの標準機能で実現する方法を解説しています。

 

クラスでの変数の扱い方(復習)

インスタンス変数とクラス変数

クラスを扱ううえで、登場する変数は「インスタンス変数」と「クラス変数」の2つあります。

本記事はインスタンス変数の話ですが「まだ区別がつかないよ!」という人向けに、まずはかんたんに解説。

 

インスタンス変数ってなに?

インスタンス変数は文字通りインスタンスごとに独立した変数です。

以下のように設定、取得ができます。

self.変数名 = 値 # 値を設定
self.変数名 # 変数から値を取得

クラス内のメソッドからインスタンス変数にアクセスするときには、必ずselfを付けてあげます。

selfはそのインスタンスそれ自身を指しているので、他のインスタンスを参照したりするのはできません。

かんたんに使い方を示すと以下のようになります。

class MyClass():
    def __init__(self):              # インスタンスを初期化するときに自動で呼ばれる
        self.val = "This is A"     #インスタンス変数 val を設定

    def get_val(self):
        return self.val           #インスタンス変数 val を返す

    def print_val(self):
        print(self.val)           #インスタンス変数 val を画面に出力


c = MyClass()    #クラスMyClassのインスタンスを作る
                 #(ここで初期化__init__()が呼ばれて 
                 # self.valに値が入る)

print(c.val)        # "This is A"
print(c.get_val())  # "This is A"
c.print_val()      # "This is A"

下の3行は同じ結果になります。

container.valのように直接インスタンス変数にアクセスするのが気持ち悪いときは、container.get_val() みたいにインスタンス変数にアクセスするためだけのメソッド(アクセサ)を定義します。

値をセットするときは以下のようになります。

container.set_val("This is B")
container.val = "This is B"

container.print_val()   # “This is B”

 

 

クラス変数ってなに?

インスタンス変数はインスタンスごとに独立した存在でしたが、クラス変数は全てのインスタンスに共通する変数です。クラス変数にアクセスするだけなら、インスタンスを生成する必要すらありません。

つまり、こういうクラスがあるときは

class MyClassB():
    val = 1     # これがクラス変数

    def do_something(self):
        print(MyClassB.val)

 

こんな感じでクラス変数にアクセスします。

print(MyClassB.val)     # 1

c = MyClassB()
c.do_something()       # 1

上のprint文と、下の2行は同じ結果になります。

クラス変数にはselfを付けません。

クラス変数は、変数として使うだけでなく、定数を定義するときによく使います。

 

インスタンス変数に文字列でアクセスする(結論)

インスタンス名.変数名でかんたんにインスタンス変数にアクセスできるのですが、「インスタンス変数名を文字列で指定して動的なアクセスをしたい」ときが(時々)あります。

これは実はPythonの標準機能で実現できます。

 

インスタンス変数を文字列で指定して取得する

getattr() を使います。

組み込み関数なので、importなどは必要ありません。

val = getattr(インスタンス, “変数名”)

 

このようなクラスがあるとき

class MyClassC():
    def __init__(self):
        self.val_a = "This is A"
        self.val_b = "This is B"

 

インスタンス変数 val_a の値を取得したいときは

c = MyClassC()
b = getattr(c, 'val_a') # インスタンス変数 val_a を取得
print(b)        # "This is A"

print(c.val_a)  # "This is A"

 

このような感じで文字列を指定してインスタンス変数の中身を取り出せます。

もちろん、文字列の部分は任意の変数に置き換えてもOK。

 

インスタンス変数を文字列で指定して定義する

setattr() を使います。

こちらも組み込み関数。

setattr(インスタンス,"変数名", 値)

 

上のクラスの例だと、

setattr(c, 'val_c', "This is C")
print(c.val_c)  # "This is C"

 

すべてのインスタンス変数名を文字列として取得

上記に関連して、知っておくと便利な機能を紹介。

インスタンスに紐付いているすべてのインスタンス変数を取得するにはどうしたらいいでしょうか?

__dict__ プロパティを使います。

これを使うと、すべてのインスタンス変数名を文字列で取得することもできます。

class MyClassC():
    def __init__(self):
        self.val_a = "This is A"
        self.val_b = "This is B"

c = MyClassC()
dict_vals = c.__dict__  # インスタンス c の要素を全て取得
pprint.pprint(dict_vals, indent=1, width=40)

# {'val_a': 'This is A',
#  'val_b': 'This is B'}

 

まとめ

Pythonでインスタンス変数に文字列を指定してアクセスする方法を解説しました。

柔軟な方法で、しかもとてもかんたんに、インスタンス変数にアクセスできるのが確認できました。

Pythonの自由度の高い言語仕様を生かして、ぜひプログラミングを楽しんでください!

 

  • この記事を書いた人

次世代ペンギン

長いのでペンギンとお呼びください。システム開発・プログラミングのお仕事をしています。甘味とコーヒーは生命線。多くの人に役立つ情報のシェアが目標です。

人気の記事

1

会社員でプログラマーとして働いている人、インフラやネットワークのエンジニアとして働いている人の中には、フリーランスのプログラマーとして独立、もしくは転向したい人もいるので ...

2

キャリアアップのため、または高収入を目指して、しっかりプログラミングを学びたいという人が増えてきましたね。 この記事では現役のエンジニアである私が、実際に仕事で稼げるよう ...

3

フリーランスのプログラマーにとって収入の向上に最も直結するのはスキルです。 必要なスキル、スキルの獲得方法が気になる人も多いでしょう。 また、これからフリーランスを目指す ...

4

Vuetifyの v-progress-circular コンポーネントは、数値データや処理状況を環状(円状)のデザインで教えてくれるUIデザインです。 ローディングのス ...

5

Vuexのstore(ストア)を使うと、各コンポーネント間で個別にデータのやり取りすることなく、データを一元的に管理できます。Vueでは欠かせない機能といえるでしょう。 ...

-Python, Tech
-

© 2021 ペンギンのーと