YukiPressプログラミング・システム開発全般についての勉強と情報発信YukiPress【Python】クラスの特性、クラス・関数のスコープの特殊性Python2021.03.13※この記事は、Pythonのクラスの特殊性とスコープについて私が独自に検証・調査した記事ですが、私自身がPythonのスペシャリストと言える程の腕前の者ではないので、内容はあくまでご参考程度にお願い致します。発端Python言語の創始者であるGuidoさんが、ある時、↓のツイートをしていました。1」が出力されます(3.9.1で実行)。1」が出力されそうに思います。...?この記事では、Pythonのスコープの特殊性に関して、調べたことをまとめています。疑問点の整理インスタンス化されていないクラス(Cクラス)の中が、なぜ実行されているのか?なぜ、xとyで結果の値が異なるのか?1は知ってる人は知っているのかもしれません。Pythonのクラスの特性オブジェクト指向(OOP)では、クラスの要素としては変数ないし関数(やプロパティ)が定義されることが普通だと思うので、定義の直下にprintなどと書くケースは不自然に思えます。処理を定義して使い回すなら、関数(上の例で言えばdef)を使用するのが自然でしょう。Pythonはクラス定義の直下に直接printなどの処理を記述できるようです(不思議なことに)。↓のようなコードを実行してみます。C()print(a.x)F()結果は、こうなります。Cは定義時点で一度実行されていることが分かります。関数F()は定義時点では実行されていません(呼び出した時に実行されている)。ここから分かるクラスの特性として、クラスは定義段階で中の処理が実行されるクラス定義直下に処理(C#で言うステートメント)を記述できるただ、こういう、複雑な書き方は普通しないと思います。Pythonのクラスはちょっと不思議ですね(何か理由があるのかもしれませんが...そこまでは調べていません)。(1)の回答としては、こんなところでしょうか。クラスのスコープにまつわる不思議もう1つの疑問は、「なぜ、xとyで結果の値が異なるのか?」でした。念のため補足すると、関数の下にクラスを書き、そのクラスを関数の如く実行するという変(というか複雑)な作り方は、普通はしないと思います。コードが大規模かつ複雑になってくると、意図せず作り込んでしまう可能性はありそうですが。Pythonのこの辺の特殊性を事前に把握しておくことで、意図せぬバグの作り込みを防げるかもしれません(あと、私の凝り性の性格もあるので調べた)。overflowにあった以下の質問・回答が参考になるかもしれません。質問のコードも、今回↑で挙げたものと、ほぼ同様です。cellは、要するにクロージャのまとまりのことであると解釈してよいでしょう。クロージャについてはPython特有の概念ではないので、詳しくはググって頂くか、クロージャ(Wikipedia)をご覧下さい。要するに、関数の中に関数を書くという形で、参照の範囲を限定するものであるようです(実務で使用した経験はありませんが)。1つ、Python公式サイトのドキュメントにヒントがありました。入れ子状のスコープです。PEP?をご覧下さい。2.1の最も重要な変更点は、この問題を解決するために静的なスコープが追加されたことです。ステートメントの割り当てによって)、変数の参照は外側のスコープのローカル名前空間で検索されます。ルールや実装の詳細はPEPで参照できます。scopeと呼ぶらしい)がバージョン2.1から導入され、こういう挙動になり(上で書いた通り)、変数の割当がない場合は外側のスコープで名前が検索されるらしいです。f()の値が使用される、ということになるようです。バグではなく、こういう挙動(要するに仕様)である、ということですね。227では、こういう説明も付け加えられています。問題を起こしうる書き方ですが、そもそも、そういうコーディングをする時点で問題があります。この変更は、同じ変数名がモジュールレベルと関数の定義が含まれている関数内のローカルの両方で変数名として使用されているコードで、互換性の問題を引き起こす可能性があります。気にしなくてよいでしょう。そのようなコードはそもそも最初から相当こんがらかっているので。補足(内部関数の場合を試してみる)クラスを関数に変えてみると、どうなるでしょうか。関数の下のクラスを関数に変えてみましたが、これはエラーになります。sub_f()f()こんなエラーメッセージが出る。無くすと、クロージャとして機能してくれるようです。1」が出力結果として、帰ってきます。2.1は2001年4月に公開されたとのことですが、Python(というかCPython)って実は歴史的な積み重ねが色々とあるのですね。静的スコープや動的スコープについては、また別の記事にまとめてみたいと思います(暇があれば)。Python広告TwitterFacebookはてブPocketLINEコピーYukiPressYukiPress関連記事Python【Python】smtplibでメール送信してみるPython標準モジュールのsmtplibを使用しSSL通信・認証付きでメール送信するコード例です。朝日新聞の長文要約生成APIを叩くPythonプログラムを、標準ライブラリだけで使ってみました。上記2点は必ず事前にインストールする。あってもPython環境を構築する手順をまとめた記事です。文字列差分比較のためのPython標準モジュールであるdifflibの使い方をまとめたものです。本サイトについて情シスSE(開発業務もしています)。本サイトは主に勉強のアウトプットが目的です。Reserved.ホーム検索トップサイドバータイトルとURLをコピーしました。