前書き
ふと Python をぶち壊したくなる衝動に駆られませんか?ぼくはたまにあります。
この記事では、1行でカンタンに Python を破壊する方法を紹介します。
まず「破壊」を定義する
どのような状態を「破壊された」とするかは、人それぞれだと思います。今回は次の2つの条件を満たす状態とします。
import
でモジュールをインポートできない- Python の組み込み関数が使えない
組み込み関数が使えないのでprint()
やrange()
が使用できず、インポートもできないので外部のモジュールを活用できません。そもそもexit()
できないので、インタプリタを閉じることもできなくなります。最低限とは言え、十分破壊できたと言えるのではないでしょうか。
実際に1行で破壊する
まずPythonを立ち上げます。バージョンは 3.6.5 で Windows 10 上で動かしています。
|
|
次の1行を実行すると壊れます。
|
|
壊れたか確認する
まず import してみます。
|
|
エラーが出ます。次に組み込み関数を使ってみます。
|
|
もう Hello world すらできなくなりました。諦めてインタプリタを終了しましょう。
|
|
終了もできません。お疲れさまでした。
解説
公式ドキュメント によると、Python 3 において、組み込み関数globals()
は次のようなものです。
現在のグローバルシンボルテーブルを表す辞書を返します。これは常に現在のモジュール (関数やメソッドの中では、それを呼び出したモジュールではなく、それを定義しているモジュール) の辞書です。
インタプリタを起動した直後に呼び出してみます。
|
|
色々と入っていますね。組み込み関数たちは __buildins__
に格納されています。例えばみんな大好きprint()
は、次のように呼び出すこともできます。
|
|
普段使うimport
も実は build in function です。ドキュメントにも記載があります。
注釈
これは
importlib.import_module()
とは違い、日常の Python プログラミングでは必要ない高等な関数です。この関数は
import
文により呼び出されます。 (builtins
モジュールをインポートしてbuiltins.__import__
に代入することで) この関数を置き換えてimport
文のセマンティクスを変更することができますが、同様のことをするのに通常はインポートフック (PEP 302 参照) を利用する方が簡単で、かつデフォルトのインポート実装が使用されていることを仮定するコードとの間で問題が起きないので、このやり方は 強く 推奨されません。__import__()
を直接使用することも推奨されず、importlib.import_module()
の方が好まれます。
推奨されないらしいですが、みんな大好きimport numpy as np
は次のようにも書けます。
|
|
つまり、組み込み関数が保持されているglobals()['__buildins__']
を適当な値で上書きすれば破壊できるというわけでした。
感想
役に立つ場面はないと思います。