web-dev-qa-db-ja.com

変数のシャドウイングを回避するPythonの方法は何ですか?

変数のシャドウイングまたはローカル変数の乗算につながる次のコードがよくあります

def whenadult(age):
    return 18 - age

age = 5
needtowait = whenadult(age)

ageは、メインコードと同じように関数に渡される場合と同じ論理的役割を持っているため、whenadultでl_ageのようなものを作成しないようにしたいと思います。

"shadowing vs. variable multiplication"ジレンマを解決するPythonの方法は何ですか?

更新:私がPythonベストプラクティス(ローカル変数スコープとグローバル変数スコープではなく)を探していた)を探していたことを明確にしたいコメントのフォローアップ

24
WoJ

ローカル変数(および関数パラメーター)ageがプログラムの他の場所の変数と同じ名前になっているという事実は無関係です。ローカル変数の要点は、それらが定義されている関数のローカルスコープ内にのみ存在するということです。

ローカル変数が他の場所で引数として使用されている変数と同じ名前であることは特に問題ではありません。実際、これは実際のコードでは非常に一般的です。たとえば、ランダムなstdlibモジュール、cmdの3.3バージョン、 Cmd.onecmd メソッドを選択すると、lineという名前の変数があり、それは次のように渡されます。 self.defaultメソッドへの引数。これは、lineという名前のパラメーターにバインドします。

引数に使用されている変数がたまたまグローバル変数であり、アクセスできるローカル変数がない場合、同じ名前は、実際にそのグローバル変数にアクセスしたいと思わない限り、問題にはなりません。あなたが既存のコードでしたくない、そしてほとんど決してすべきではありません。この場合、そして実際のほとんどの場合、それは単なる偶然であり、何も意味せず、何も影響を与えません。解決する必要のある問題ではありません。


あなたが抱えている問題は、PyCharmがageでグローバルwhenadultにアクセスできるようにしたいかどうかを推測できないことです。人間が同様に混乱し、コードの理解を遅くする可能性はありますか(この些細なケースでない場合は、より複雑なケースかもしれません)。それとも、コードレビューアや教師などが警告なしでリンターをパスしないためにコードを拒否するような環境で、いつかコードを書かなければならないということですか?多分。

しかし、実際には、このような環境では、そもそもグローバル変数を使用することについて不満を言うでしょう。そして、あなたは本当にここにいる必要はありません。 ageがグローバルである唯一の理由は、トップレベルのコードにアクセスできる必要があることです。そのコードを関数に移動すると、ageがその関数のローカルになる可能性があります。例えば:

def whenadult(age):
    return 18 - age

def main():
    age = 5
    needtowait = whenadult(age)

main() # possibly with an if __name__ == '__main__' guard

これは、PyCharmを幸せにし、リンターツールや、混乱しやすい、または厳格な人間の読者を喜ばせます。それはあなたのコードをほんの少し速くするでしょう。一方、読み取るコードは3行と1インデントだけですが、プログラム全体は8行しかありません。したがって、ケースバイケースで行うことができるトレードオフです。

48
abarnert

PyCharmで変数をシャドーイングするという警告を受けたときはいつでも。慣習として、アンダースコアのプレフィックスを使用するようにローカル変数の名前を変更しようとします。これは、グローバル変数をmain()関数にラップすることに加えて検討するもう1つの方法です。

    def whenadult(_age):
        return 18 - _age

    age = 5
    needtowait = whenadult(age)
4
Devy