ラスボス系後輩ヒロインAIチャットボットを作りたい・Pythonの基礎⑤

公開日:2019-03-08
最終更新:2019-03-22
※この記事は外部サイト(https://qiita.com/perpouh/items/f9c7b739bb...)からのクロス投稿です

前回の続きから行きます。

名前空間とスコープ

Pythonにも名前空間というものがあります。が、ちょっと読んだ感じ特殊です。

>>> fluit = "orange"  
>>> def test1():  
...   print(fluit)  
...   
>>> test1()  
orange  

はい。
で、

>>> def test2():  
...   fluit = "strawberry"  
...   print(fluit)  
...   
>>> test2()  
strawberry  
>>> print(fluit)  
orange  

はい。この時点でちょっと「おや?」となりました。グローバル変数にアクセスできてるのかできてないのかどっち?という感じになります。
そんでこう。

>>> fluit = "orange"  
>>> def test3():  
...   print(fluit)  
...   fluit="strawberry"  
...   print(fluit)  
...   
>>> test3()  
Traceback (most recent call last):  
  File "<stdin>", line 1, in <module>  
  File "<stdin>", line 2, in test3  
UnboundLocalError: local variable 'fluit' referenced before assignment  

ええ……?
と思ったのですが、これを読み解くには以下の情報が必要です。

  • メソッドはグローバル変数を参照できます(test1)。
  • メソッドはグローバル変数を上書きできません(test2)。
  • メソッドはグローバル変数と同名のローカル変数を持つことができます(test2)。

ポイントはtest1の時点で、グローバル変数を暗黙的に呼んでいるというところです。
test3についても、メソッド一行目で暗黙的にグローバルのfluit変数が読み込まれています。
で、なぜか2行目でもグローバルの方を書き換えに行ってエラーが発生するということ らしい です(あやふや)。

できないならローカル変数作ったらええやんけと思うんですが、まあグローバル変数にアクセスするときは global つけようねということで収めるのがいいっぽい。

>>> fluit = "orange"  
>>> def test3():  
...   global fluit  
...   print(fluit)  
...   fluit="strawberry"  
...   print(fluit)  
...   
>>> test3()  
orange  
strawberry  

ちょっとこの宣言(メソッド一行目)気に食わないけど、そもそもグローバル変数とローカル変数で名前がかぶるのがバッドプラクティスっぽいのでそのへんはアレでアレしましょう。んーでもなーthisとかselfに慣れちゃってるのでキモいっちゃキモい……。

名前の中の_と__

先頭と末尾が2個のアンダースコアになっている名前は、Pythonが使う変数として予約されている。(中略)このパターンが選ばれたのは、アプリケーションデベロッパーが自分の変数のためにこのような名前を選ぶことはまずないだろうと思われたからだ。

どうかな……(感想)

以前サンプルでanswerというメソッドを扱った時、実はdocstringを書き込んでいました。

def answer():  
  '''  
  これO'Railly本のサンプルそのままなんですけど名前がanswerで答えが42なのわらう。  
  銀河ヒッチハイクガイドだ  
  '''  
  print(42)  

これを前提にanswer.__doc__を出力してやると、以下のようになります。

>>> answer.__doc__  
"\n  これO'Railly本のサンプルそのままなんですけど名前がanswerで答えが42なのわらう。\n  銀河ヒッチハイクガイドだ\n  "  

これどうなんだろうな、エラーログ出力くらいにしか使わない気がするのだけど。

エラー処理とtry、except

するか、しないかだ。お試しはない。 ――Yoda

Yodaってアレかしらスターウォーズ? 見ていないのでわからないですけど。

try:  
  code  
except Exception as name:  
  code  

の形式を取ります。べつだん奇矯でもないですね。
組み込み例外の一覧はドキュメントを見るのが早そう:PythonDoc

独自例外クラス

Pythonでももちろん独自例外を実装することができます。

class OriginalException(Exception):  
  pass  

で、あとは

raise OriginalException(引数)  

するだけ。クラス定義に括弧があるのは珍しいですね。括弧の中が親クラスということらしいです。
カンマで区切って複数指定することで多重継承もできるらしいですが、多重継承じたいにあんまり馴染みがないのでどうだろうか。Swiftとかも書くので慣れた方がいいのだろうとは思います。

Pythonの多重継承の際の初期化とメゾットについて - Qiita

まあこのへんはおいおいやっていきましょう。

で、次はNumPyに進む予定でしたが、ちらっと読んでみたところ、これ線形代数を先にやった方がいいのでは?となったので線形代数に行きます。私の数学の知識は数ⅡBで止まっています(微積とベクトルがギリ)。大丈夫だろうか。

記事が少しでもいいなと思ったらクラップを送ってみよう!
18
+1
@perpouhの技術ブログ

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする