Python
 Computer >> コンピューター >  >> プログラミング >> Python

文字列をPythonのクラスオブジェクトに変換する方法|eval()とgetattr()の使い分け

Pythonでは、関数の引数として受け取った文字列をもとに、現在の名前空間内に同じ名前のクラスが存在する場合、その文字列からクラスオブジェクトを取得したい場面があります。例えば、設定ファイルやユーザー入力から動的にクラスを呼び出すような処理です。

本記事では、文字列をクラスオブジェクトに変換する代表的な2つの方法を、サンプルコード付きで解説します。

方法1:eval()を使う

eval()関数は、渡された文字列をPythonの式として評価するため、クラス名を含む文字列を直接クラスオブジェクトに変換できます。

サンプルコード

class Foobar:
    pass

print(eval("Foobar"))
print(type(Foobar))

実行結果(Python 2の場合)

__main__.Foobar
<type 'classobj'>

Python 3では出力が <class '__main__.Foobar'><class 'type'> のように表示されます。

注意点

eval()は任意のコードを実行できてしまうため、外部からの信頼できない入力に対して使用するとセキュリティリスクが非常に高くなります。ユーザー入力を扱う場合は、次に紹介するgetattr()を使った方法を推奨します。

方法2:getattr()とsys.modulesを使う

sys.modules[__name__]で現在のモジュールを取得し、そこからgetattr()で属性(クラス)を取り出す方法です。eval()と比べて安全で意図も明確なため、実務ではこちらが好まれます。

サンプルコード

import sys

class Foobar:
    pass

def str_to_class(class_name):
    return getattr(sys.modules[__name__], class_name)

print(str_to_class("Foobar"))
print(type(Foobar))

実行結果(Python 2の場合)

__main__.Foobar
<type 'classobj'>

解説

  • sys.modules[__name__]:実行中のモジュール自身への参照を取得します。
  • getattr(モジュール, 文字列):指定した名前の属性(ここではクラス)を動的に取得します。
  • 元のコードでは仮引数名に組み込みのstrを使用していますが、組み込み型を上書きしないためにも、上記のように別の名前にすることをおすすめします。

また、存在しないクラス名を渡した場合に備え、以下のようにAttributeErrorをハンドリングしておくとより堅牢になります。

def str_to_class(class_name):
    try:
        return getattr(sys.modules[__name__], class_name)
    except AttributeError:
        raise ValueError(f"クラス '{class_name}' は見つかりません")

まとめ

方法メリットデメリット
eval()シンプルに書ける任意のコード実行の危険性があり、非推奨になりつつある
getattr() + sys.modules安全で意図が明確対象が現在のモジュール内のクラスに限られる

動的にクラスを取得したい場合は、安全性の観点からgetattr()を使う方法がベストプラクティスです。他のモジュールのクラスを扱いたい場合は、importlib.import_module()と組み合わせることで柔軟に対応できます。

  1. 文字列をJavaScriptオブジェクトに変換する方法【JSON.parse()の使い方】

    JavaScriptでJSON形式の文字列をオブジェクトに変換するには、JSON.parse()メソッドを使用します。このメソッドは、引数に渡された文字列を解析(パース)し、対応するJavaScriptオブジェクトを返します。 サンプルコード <!DOCTYPE html> <html lang=ja> <head> <meta charset=UTF-8 /> <meta name=viewport content=width=device-width, initial-scale=1.0 /> <title>Docum

  2. Pythonで文字列をバイナリ(2進数)に変換する方法をわかりやすく解説

    Pythonで文字列をバイナリに変換する基本の考え方Pythonで文字列をバイナリ(2進数)表現に変換するには、文字列内の各文字を1つずつ取り出し、それぞれを2進数へ変換したうえで、結果をひとつの文字列として連結します。各文字の文字コードは ord() 関数で取得でき、format() 関数に「b」フォーマット指定子を渡すことで、簡単に2進数形式へ整形できます。format() と ord() を使った変換方法最もシンプルなのが、format(ord(x), b) を使って各文字 x を2進数の文字列に変換する方法です。次の例では、文字列 hello world の各文字をスペース区切りのバイ