2016-08-23 26 views
-1

私はむしろPythonには新しく、以下のコードで関数とif文がなぜ "83"の代わりに "100"を返すのか不思議でした。私は明白な何かを見逃しているかどうかわからないが、それがうまくいくかのように思える。 This is the code I'm refering to:python cantは変数の値を変更する関数を使用します

playerhp = 100 
def attack1(x): 
    x = (x - 17) 
    return x 

while playerhp > 0: 
    enemyattack = input("please type the word 'attack': ") 
    if enemyattack.upper() == "ATTACK": 
     attack1(playerhp) 
     print(playerhp) 
    else: 
     break 
+3

コードがテキストです。そのテキストをここにコピーして貼り付けてください。スクリーンショットは適切ではありません。 –

+0

あなたの関数は、そのグローバルオブジェクトを修正するつもりはなく、分かり易さを理解していても欲しくないでしょう。スコープについて理解するために、Pythonチュートリアルを読んでみてください。 –

+3

@ MrN3MESISいいえコメントにあなたのコードを載せてはいけません。あなたは実際に人々がそれを読むことを試みることを期待していますか?元の質問に投稿してください。一番簡単なのは、テキストエディタからコピー&ペーストして貼り付けたものを強調表示し、control-kを押すことです。 –

答えて

0

上記のコメントに記載されているとおり、この問題はスコープになります。詳細については、グーグルで試してみてください。しかし、ここでは初心者レベルの説明をしようとします。

変数を宣言するとき、変数は特定のスコープ内に存在し、同じまたは低いスコープの変数によってのみアクセスできます。例えば、それは下のものにアクセスできるように

var1 = 5 
if var1 < 6: 
    print(var1) 
    var2 = 7 
print(var2) #error on this line 

var1は、この例では、最も高い範囲内に存在するので、print(var1)ラインが正常に動作します。ただし、var2は、印刷しようとしている文よりも高い範囲にあり、変数を見つけることができません。 Pythonは良い書式設定を強制するので、インデントの各レベルとしてスコープを広く考えることができます。インデントされたセクションに移動する必要がある場合は、それを見つけることができますが、インデントされていないセクションを検索する必要がある場合は、検索できません。

これは機能にまで及ぶ。あなたの関数attack1は、あなたのwhileループの内部とは異なるスコープに存在し、変数xはその関数内にのみ存在します。したがって、xを変更すると、元のスコープでは変更されません。あなたの元の質問の範囲を超えていますが、passing by valuepassing by referenceの意味とそれらがPythonにどのように適用されるかを調べてください。他の回答が指摘するように、あなたはすなわち

playerhp = attack1(playerhp) 

は、新しい番号を取るために、あなたが渡している元の数にxのreturn valueを割り当てることによってこの問題を解決することができ、それがあること、そしてそれを再割り当てするために使用されるよりも少ない17元の値に戻すので、代わりにこの新しい値を引き継ぎます。他の回答は、一部の人々は、直接グローバル変数を変更することをお勧め

を示唆するものにに関して

編集。 (ここではPython 3と仮定していますが、どのバージョンを使用しているのか、Python 2が異なるのか分かりません)、あなたはそれを行うことができます。 Pythonは機能のうち、スコープについて少しおかしいですが、このようなあなたの攻撃機能を書き換えることは簡単です:

def attack1(): 
    global playerhp 
    playerhp -= 17 #shortcut to subtract 17, same as playerhp = playerhp - 17 

、あなたは単に

attack1() 

でそれを呼び出すことができ、それは同じように動作します方法。あなたがそれを避けることができれば、多くのプログラマーはグローバル変数の使用を躊躇しますが、それは非常に主観的で、時間の終わりまでそれについて終日戦います。

+0

"attack1(playerhp)"という変数を "playerhp"という変数に代入しないことで、関数内のplayerhpの値をパラメータとして変更するだけで、print文は無視されますそれが最初に割り当てられたときにplayerhpを印刷するだけですか? – MrN3MESIS

+0

これはスコープに関連しています。 'attack1(x)'を呼び出すと、更新される関数に 'playerhp'のコピーが渡されます。しかし、 'playerhp'の実際の値は変わりません。したがって、値を更新するには、関数ORによって値が返されたら 'playerhp'を更新するか、グローバルで達成される関数内の変数に同じ参照を使用する必要があります –

+1

@ MrN3MESIS Moinuddinはちょうど言ったことと同じです。私が私の答えで言いましたように、Googleは「値渡し」と「参照渡し」を行い、どちらがPythonを使用しているかを把握しています。これは、すべての単一プログラミング言語で理解するための重要な情報です。ヒント: 'playerhp'の値を変更しない' x'は、値渡しを示唆しています。 – Cody

2

あなたはplayerhpattack1の戻り値を代入する必要があります。

def attack1(x): 
    x = (x - 17) 
    return x 

playerhp = 100 
while playerhp > 0: 
    enemyattack = input("please type the word 'attack': ") 
    if enemyattack.upper() == "ATTACK": 
     playerhp = attack1(playerhp) 
     print(playerhp) 
    else: 
     break 
+0

それは感謝します。変数が割り当てられている場所を変更した理由を尋ねてもいいですか? – MrN3MESIS

0

はここにあなたのコードの作業例です:

playerhp = 100 


def attack1(x): 
    x = (x - 17) 
    return x 

while playerhp > 0: 
    enemyattack = input("please type the word 'attack': ") 
    if enemyattack.upper() == "ATTACK": 
     playerhp = attack1(playerhp) 
     print(playerhp) 
    else: 
     break 

しかし、あなたの質問について、最も重要なのはありますあなたは実際に引数がどのように働いているかを実際に理解しています。それを説明しているサイトがたくさんあります。ここにはちょうどone

0

これを達成するには2つの方法があります。

アプローチ1attack1()によって値のリターンに基づいて 更新playerhpの値。

>>> playerhp = 100 
>>> def attack1(x): 
...  return x -= 17 
... 
>>> playerhp = attack1(playerhp) 
>>> playerhp 
83 

アプローチ2:たとえばattack1()へのparamとしてxを渡さないでください。代わりのような関数内global playerhpを使用します。

>>> playerhp = 100 
>>> def attack1(): 
...  global playerhp 
...  playerhp -= 17 
... 
>>> attack1() 
>>> playerhp 
83 
0
#this works for me. You were not printing the result of the function. 
def attack1(x): 
    return(x-17) 

playerhp=100 
while playerhp>0: 
    enemyattack= input("Please type the word 'attack':") 
    if enemyattack.upper()=="ATTACK": 
     x=attack1(playerhp) 
     print (x) 

    else: 
     break 
関連する問題