0

私は Python がどのように機能するかについて学んでいますが、しばらく読んだ後でも、グローバルと適切な関数引数についてまだ混乱しています。グローバルが関数内で変更されず、参照されるだけの場合を考えてみましょう。

関数の引数の代わりにグローバルを使用できますか? グローバルの使用は悪い習慣と見なされていると聞いたことがあります。この場合はそうなるのでしょうか?

引数なしで関数を呼び出す:

def myfunc() :
    print myvalue

myvalue = 1
myfunc()

引数を指定して関数を呼び出す

def myfunc(arg) :
    print arg

myvalue = 1
myfunc(myvalue)
4

4 に答える 4

2

グローバルの使用は悪い習慣と見なされていると聞いたことがあります。この場合はそうなるのでしょうか?

それはあなたが何を達成しようとしているかによって異なります。任意の値を出力することになっている場合myfunc()、...

def myfunc(arg):
    print arg

myfunc(1)

...より良いですが、myfunc()常に同じ値を出力する必要がある場合は...

myvalue = 1

def myfunc():
    print myvalue

myfunc()

...良いですが、例は非常に単純ですが、グローバルを除外して...を使用することもできます...

def myfunc():
    print 1

myfunc()
于 2013-04-25T12:13:19.997 に答える
0

関数の引数を使用する方がグローバルを使用するよりも優れている理由はいくつかあります。

  1. 混乱の可能性を排除します。プログラムが大きくなると、どのグローバルがどこで使用されているかを追跡するのが非常に難しくなります。関数の引数を渡すと、関数が使用する値をより明確にすることができます。
  2. グローバルを使用すると、最終的に犯す特定の間違いがあります。これは、何が起こっているのかを理解するまで非常に奇妙に見えます。同じ関数内のグローバル変数の変更と読み取りの両方に関係しています。これについては後で詳しく説明します。
  3. グローバル変数はすべて同じ名前空間に存在するため、名前が重複するという問題がすぐに発生します。「index」という名前の 2 つの異なる変数が必要な場合はどうすればよいでしょうか。index1それらを呼び出すとindex2、非常に混乱し、非常に速くなります。ローカル変数または関数パラメーターを使用することは、それらがすべて異なる名前空間に存在することを意味し、混乱の可能性が大幅に減少します。

ここで、同じ関数内のグローバル変数の変更と読み取り、および発生する可能性のある紛らわしいエラーについて説明しました。外観は次のとおりです。

record_count = 0  # Global variable
def func():
    print "Record count:", record_count
    # Do something, maybe read a record from a database
    record_count = record_count + 1  # Would normally use += 1 here, but it's easier to see what's happening with the "n = n + 1" syntax

これは失敗します:UnboundLocalError: local variable 'record_count' referenced before assignment

待って、何?record_count明らかにグローバルであるのに、ローカル変数として扱われるのはなぜですか? 関数でを割り当てなかった場合record_count、Python はグローバル変数を使用します。しかし、値を に代入するときrecord_count、Python はその意味を推測する必要があります: グローバル変数を変更するのか、それともグローバル変数をシャドウ (非表示) にしてローカルのみを処理する新しいローカル変数を作成するのか変数。また、Python はデフォルトで、あなたがグローバルを賢く扱っている (つまり、何をしているのか、なぜなのかを正確に知らずにグローバルを変更しない) と想定し、 という名前の新しいローカル変数を作成するつもりであると想定しますrecord_count

ただし、関数内で名前が付けられたローカル変数にアクセスしている場合record_count、Python では、関数内で同じ名前のグローバル変数にアクセスすることはできません。これは、本当に厄介で追跡が難しいバグを回避するためです。つまり、この関数にローカル変数という名前が付けられている場合record_count、代入ステートメントのために存在する場合、へのすべてのアクセスrecord_countはローカル変数にアクセスしていると見なされます。ローカル変数の値が定義される前に、ステートメントにアクセスを含めます。printしたがって、UnboundLocalError例外。

さて、読者のための演習です。UnboundLocalErrorprint ステートメントを削除し、例外がまだスローされていることに注意してください。理由がわかりますか?(ヒント: 変数に代入する前に、代入の右側の値を計算する必要があります。)

さて:本当に関数でグローバルrecord_count変数を使いたいのなら、それを行う方法は Python のglobalステートメントを使うことです。代わりにグローバル変数に割り当ててください。」それが機能する方法は、関数の最初にあるだけですglobal record_count(または他の変数名)。したがって:

record_count = 0  # Global variable
def func():
    global record_count
    print "Record count:", record_count
    # Do something, maybe read a record from a database
    record_count = record_count + 1  # Again, you would normally use += 1 here

これにより、最初に期待したことが行われます。しかし、うまくいけば、なぜそれが機能し、他のバージョンは機能しないのかが理解できます.

于 2013-04-25T12:31:20.937 に答える
0

はい。globalこれらの場合、変数を関数の引数として渡す代わりに、変数を作成すると機能します。しかし問題は、大きな関数を書き始めるとすぐに名前が足りなくなり、グローバルに定義された変数を維持するのが難しくなることです。変数を編集する必要がなく、読み取るだけの場合はglobal、関数のように定義する必要はありません。

ここでグローバル変数の短所について読んでください -グローバル変数は悪いですか?

于 2013-04-25T12:08:48.577 に答える