はじめに
PythonのWEBフレームワークであるFlaskにて、グローバル変数のgがエラーになる現象からなかなか抜け出せなかった話をするよ!
gちゃ〜ん!!
おじいちゃんみたいに呼ばないの。
Flask学習におすすめの本を紹介します。
⇨【Python】Flask入門におすすめの本 3選
グローバル変数「g」を使用するとエラーになる
import sqlite3
from flask import Flask, g
def get_db():
if 'db' not in g:
g.db = sqlite3.connect('TestDB.db')
return g.db
app = Flask(__name__)
con = get_db()
上記サンプルのget_dbメソッドでは「g」にdbがなければSQLiteのコネクションを作成しています。
実行すると、if ‘db’ not in g:の部分でRuntimeErrorが発生します。
エラーの内容を見るとWorking outside of application context.と表示されています。
結論を言うと、「g」はアプリケーションコンテキストに属する変数のようです。
アプリケーションコンテキストはFlaskのインスタンスが作成されるタイミングで同時に作成されます。
上記サンプルだと「g」に属するアプリケーションコンテキストが指定されていないためエラーになります。
エラーの対処方法
エラーを回避するため、サンプルを修正してみましょう。
import sqlite3
from flask import Flask, g
def get_db():
with app.app_context():
if 'db' not in g:
g.db = sqlite3.connect('TestDB.db')
return g.db
app = Flask(__name__)
con = get_db()
変更した箇所は、with app.app_context():の部分です。
これで、「g」はFlaskのインスタンスであるappのアプリケーションコンテキスト(app_context)に属するものとして動作し、エラーを回避できます。
Flaskのデコレータが適用されたメソッド内ではエラーにならない
まずはサンプルを見てみましょう。
import sqlite3
from flask import Flask, render_template, g
def get_db():
if 'db' not in g:
g.db = sqlite3.connect('TestDB.db')
return g.db
app = Flask(__name__)
@app.route('/')
def index():
con = get_db()
return render_template('index.html')
if __name__ == '__main__':
app.run('127.0.0.1', 5000, debug=true)
このサンプルではindexメソッド内でget_dbを記載しています。
get_db内では明示的にアプリケーションコンテキストを指定していませんが、これを実行してもエラーにはなりません。
これは、Flaskのルーティングするためのデコレータ(上記サンプルでは@app.route(‘/’))にて、インスタンスを指定しているからです。
デコレータについては下記の記事を参照ください。
まとめ
Flaskのグローバル変数「g」のエラー回避方法について解説しました。
- Flaskのグローバル変数「g」を使用するには、明示的にFlaskインスタンスのアプリケーションコンテキストを指定する必要がある。
- Flaskのルーティング用デコレータが記載されているメソッド内で使用する場合は、デコレータでFlaskインスタンスが指定されるので、エラーにならない。
最後まで読んでいただき、ありがとうございます。
Flask学習におすすめの本を紹介します。
⇨【Python】Flask入門におすすめの本 3選