Python のスコープを修正するための 5 つのポイント

大家讲道理
リリース: 2016-11-07 10:43:37
オリジナル
1063 人が閲覧しました

1. ブロックレベルのスコープ

考えてみて、この時点で次のプログラムを実行すると出力があるでしょうか?処刑は成功するでしょうか?

#块级作用域
if 1 == 1:
    name = "lzl"
print(name)
for i in range(10):
    age = i
print(age)
ログイン後にコピー

まず実行結果を見てみましょう

C:/Users/L/PycharmProjects/s14/preview/Day8/作用域/main.py
lzl
9
 Process finished with exit code 0
ログイン後にコピー

コードは正常に実行され、問題はありません。Java/C# では、上記のコードを実行すると、名前と年齢が定義されていないことが確認されますが、Python では定義できます。これは、Python ではコード ブロックにブロック レベルのスコープがないため、コード ブロック内の変数は正常に実行できます。以前に学習した知識で、関数を学習するとき、関数は個別のスコープであり、Python にはブロックレベルのスコープはありませんが、ローカルスコープがあります。次のコードを見てください

#局部作用域
def  func():
    name = "lzl"
print(name)
ログイン後にコピー

このコードを実行して、それがあるかどうかを考えてください。何か出力はありますか?

Traceback (most recent call last):
  File "C:/Users/L/PycharmProjects/s14/preview/Day8/作用域/main.py", line 23, in <module>
    print(name)
NameError: name &#39;name&#39; is not defined
ログイン後にコピー
ログイン後にコピー
これは誰でも理解できると思いますが、name 変数は func() 関数内でのみ有効なので、上記のコードを簡単に調整して結果を確認してください。

前のコードにコードを追加しました。変数名が出力される前に、関数が実行されます。この時点で出力は変わりますか?

#局部作用域
  
def  func():
    name = "lzl"
  
func()          #执行函数
print(name)
ログイン後にコピー

実行してもエラーが報告されます。先ほどの文に戻りましょう。関数が実行されたとしても、名前のスコープは関数内にのみあり、最初の 2 つの知識ポイントを覚えておいてください。 , そして次のトリックを開始します

3. スコープチェーン

関数を調整して、次のコードの実行結果を確認してください。

Traceback (most recent call last):
  File "C:/Users/L/PycharmProjects/s14/preview/Day8/作用域/main.py", line 23, in <module>
    print(name)
NameError: name &#39;name&#39; is not defined
ログイン後にコピー
ログイン後にコピー

関数を勉強したことがある方は、f1() が実行された後に Snor が出力されることを知っておく必要があります。まず概念を覚えておいてください。Python にはスコープ チェーンがあり、変数は最初に内側から外側に検索されます。自分のスコープに行って自分で見つけてください

見つからずにエラーを報告するまで、上司に探しに行きませんでした

さて、伏線はこれで十分です。究極バージョンはここにあります~~

#作用域链
  
name = "lzl"
def f1():
    name = "Eric"
    def f2():
        name = "Snor"
        print(name)
    f2()
f1()
ログイン後にコピー

f2()

最後のf2を考えてください() 実行結果は「lzl」または「eric」と表示されますか?答えを今すぐ投稿する代わりに、次のコードを見てください:

#终极版作用域
  
name = "lzl"
  
def f1():
    print(name)
  
def f2():
    name = "eric"
    f1()
ログイン後にコピー

実行結果は "lzl" です。 上記のコードの実行結果は、関数 f1 のメモリ アドレスです。つまり、ret=f1; ret() を実行することは、f1() を実行することと同じであり、f2() と f1() は同じスコープチェーン内にあります。関数内に変数がない場合は外部を参照するので、このときの変数名の値は「lzl」であることが理解できれば、答えがそうでなかったという最終的なコードの答えもわかります。今与えられました

#终极版作用域
  
name = "lzl"
  
def f1():
    print(name)
  
def f2():
    name = "eric"
    return f1
  
ret = f2()
ret()
  
#输出:lzl
ログイン後にコピー

# 出力: lzl

はい、出力は「lzl」です。関数が実行される前にスコープが形成され、スコープチェーンも生成されていることを覚えておいてください

5。質問

#终极版作用域
  
name = "lzl"
  
def f1():
    print(name)
  
def f2():
    name = "eric"
    f1()
  
f2()
ログイン後にコピー

liのタイプを判断しますか? li の要素はどのような型ですか?

li = [lambda :x for x in range(10)]
ログイン後にコピー

li がリスト型で、リスト内の要素が関数であることがわかります。そして、リストの最初の要素の戻り値を出力します。このときの戻り値は何でしょうか。

#lambada インタビューの質問

print(type(li))
print(type(li[0]))
  
# <class &#39;list&#39;>
# <class &#39;function&#39;>
ログイン後にコピー
#出力: 9

li最初の関数の戻り値は 0 ではなく 9 です。関数が実行される前に内部コードは実行されないことに注意してください。自分でブログを練習して感想を深めましょう

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!