1

以前の投稿で、BASIC と同じように Python でコーディングしていると言われました (まだ Python で「考えている」わけではありません)。これはおそらく真実であり、これが私が助けを必要とする理由です. そうは言っても、これまでに Python に関する本を 1 冊読み ( Bytes of Python )、オンラインでさらに 2 冊の本を購入し (そのうちの 1 つはInvent with Pythonで、現在読んでいます)、The New Boston から多くのチュートリアルを行いました。それでも、私の質問はあなたにとって初心者っぽいかもしれません。

FreeBasic では、変数はすべてグローバル化されています。Python では、新しい関数を作成するたびにそれらをグローバル化する必要があります。これはあまり実用的ではありません。それで、私は何をすることが期待されていますか?「ネイティブ Python スピーカー」は、この問題にどのように取り組むのでしょうか? 以下に、関数内のすべての変数をグローバル化するために作成した小さなプログラムを示します。

#-*- coding: iso8859_1 -*-

import random

ca1 = 10
ca2 = 10
taco = 20
pv1 = random.randint(1,10)
pv2 = random.randint(1,10)
cnt = 0
pv1Dep = pv1
pv2Dep = pv2
ast = "*" * 7
d20_1 = random.randint(1,20)
d8_1 = random.randint(1,8)
d20_2 = random.randint(1,20)
d8_2 = random.randint(1,8)

def intro():
    global ca1
    global ca2
    global taco
    global pv1
    global pv2
    global cnt
    global pv1Dep
    global pv2Dep
    global d20_1
    global d8_1
    global d20_2
    global d8_2


    print "Imaginez deux guerriers de D&D 2e édition qui se battent."
    print
    print "Guerrier 1: " + str(pv1) + " PV, épée longue (1-8 points de dégât), TACO de 20, CA de " + str(ca1) + "."
    print "Guerrier 2: " + str(pv2) + " PV, épée longue (1-8 points de dégât), TACO de 20, CA de " + str(ca2) + "."
    print

def nouveauCombat():
    global ca1
    global ca2
    global taco
    global pv1
    global pv2
    global cnt
    global pv1Dep
    global pv2Dep
    global d20_1
    global d8_1
    global d20_2
    global d8_2

    print ast + "NOUVEAU COMBAT" + ast
    print
    while ((pv1 > 0) and (pv2 > 0)):
        cnt = cnt + 1
        print ast + "ROUND " + str(cnt) + ": INITIATIVE" + ast
        print
        calcInitiative()
        print
    print ast + "RESULTAT" + ast
    print
    resultat()

def calcInitiative():
    global ca1
    global ca2
    global taco
    global pv1
    global pv2
    global cnt
    global pv1Dep
    global pv2Dep
    global d20_1
    global d8_1
    global d20_2
    global d8_2

    initiative1 = random.randint(1,10)
    initiative2 = random.randint(1,10)
    print "Le guerrier 1 fait son jet d'initiative."
    print str(initiative1) + "!"
    print
    print "Le guerrier 2 fait son jet d'initiative."
    print str(initiative2) + "!"
    print
    if initiative1 == initiative2:
        print "Les deux guerriers attaquent au même moment."
        print
        print ast + "ROUND " + str(cnt) + ": ATTAQUE" + ast
        print
        attaque1()
        print
        attaque2()
    elif initiative1 < initiative2:
        print "Le guerrier 1 attaque en premier."
        print
        print ast + "ROUND " + str(cnt) + ": ATTAQUE" + ast
        print
        attaque1()
        print
        if pv2 > 0:
            print
            attaque2()
    else:
        print "Le guerrier 2 attaque en premier."
        print
        print ast + "ROUND " + str(cnt) + ": ATTAQUE" + ast
        print
        attaque2()
        print
        if pv1 > 0:
            print
            attaque2()

def attaque1():
    global ca1
    global ca2
    global taco
    global pv1
    global pv2
    global cnt
    global pv1Dep
    global pv2Dep
    global d20_1
    global d8_1
    global d20_2
    global d8_2

    print "Le guerrier 1 fait son jet de toucher."
    print str(d20_1) + "!"
    if d20_1 >= ca2:
        print "Touché!"
        pv2 = pv2 - d8_1
        print str(d8_1) + " points de dégât!"
        print "Le guerrier 2 est à " + str(pv2) + "/" + str(pv2Dep) + " PV!"
    else:
        print "Raté!"

def attaque2():
    global ca1
    global ca2
    global taco
    global pv1
    global pv2
    global cnt
    global pv1Dep
    global pv2Dep
    global d20_1
    global d8_1
    global d20_2
    global d8_2

    print "Le guerrier 2 fait son jet de toucher."
    print str(d20_2) + "!"
    if d20_2 >= ca1:
        print "Touché!"
        pv1 = pv1 - d8_2
        print str(d8_2) + " points de dégât!"
        print "Le guerrier 1 est à " + str(pv1) + "/" + str(pv1Dep) + " PV!"
    else:
        print "Raté!"

def resultat():
    global ca1
    global ca2
    global taco
    global pv1
    global pv2
    global cnt
    global pv1Dep
    global pv2Dep
    global d20_1
    global d8_1
    global d20_2
    global d8_2

    print "Le combat prend fin au round " + str(cnt) + "."
    print

    if pv1 == pv1Dep:
        print "Le guerrier 1 n'a pas la moindre égratignure."
    elif pv1 > 0:
        print "Le guerrier 1 est blessé."
    else:
        print "Le guerrier 1 est mort."

    print "Il finit le combat avec " + str(pv1) + "/" +str (pv1Dep) + " PV."
    print

    if pv2 == pv2Dep:
        print "Le guerrier 2 n'a pas la moindre égratignure."
    elif pv2 > 0:
        print "Le guerrier 2 est blessé."
    else:
        print "Le guerrier 2 est mort."

    print "Il finit le combat avec " + str(pv2) + "/" +str (pv2Dep) + " PV."
    print

intro()
nouveauCombat()
4

4 に答える 4

3

代入しない限り、名前をグローバルとして宣言する必要はありません。

a = 1
b = 2
def foo():
    global b
    print a # prints 1
    b = 3
foo()
print b # prints 3
于 2011-08-09T18:13:10.007 に答える
2

Python では、多くの現代言語と同様に、グローバル変数の多用はアンチパターンと見なされます。理由はたくさんあります:

  • これは、効率的なマルチスレッド コードにとって重要な関数の再入可能性を妨げます。
  • 単体テストが難しくなり、中規模から大規模のプロジェクトに役立ちます
  • モジュールの相互依存性が高まり、問題の追跡と発見後の修正が難しくなります。

各関数が必要とするデータを渡すように努力する必要があります。

def foo():
    bar = 10
    baz(bar)

def baz(bar):
    print bar

ある関数から次の関数に状態をキャプチャする必要がある場合は、それをクラスにラップできます。

class quux(object):
    def __init__(self):
        self.a = 1
        self.b = "two"

def foo():
    bar = quux()
    baz(bar)
    print bar.a, bar.b

def baz(bar):
    bar.a = len(bar.b)

要約すると、グローバルはほとんど必要ありませんが、多くの場合、グローバルではないものが必要です。

于 2011-08-09T19:07:50.327 に答える
2

オブジェクト指向プログラミングの基本を紹介するために、あなたのプログラムを再編成しました。クラスとオブジェクトについて学ぶ必要があります。文字列をまとめる正しい方法については、文字列の書式設定も確認する必要があります。

基本的に、プレイヤー オブジェクトを 2 つ作成し、その 2 人のプレイヤー用の戦闘オブジェクトを作成します。次に、実際に戦闘を行うために、戦闘オブジェクトのメソッドを呼び出します。クラスのインスタンスがそれ自体を参照する方法です。優れた Python チュートリアルは、これらすべてについて教えてくれるはずです。self

残っている唯一のグローバル変数は定数ですast。グローバル定数は、場合によっては問題ありません。

#-*- coding: iso8859_1 -*-
import random
ast = "*" * 7

class Player(object):
    def __init__(self, num, ca):
        self.ca = ca
        self.num = num
        self.pv = random.randint(1,10)
        self.d20 = random.randint(1,20)
        self.d8 = random.randint(1,8)
        self.pvDep= self.pv

class Combat(object):
    def __init__(self, player1, player2):
        self.player1 = player1
        self.player2 = player2
        self.cnt = 0

    def intro(self):
        print "Imaginez deux guerriers de D&D 2e édition qui se battent."
        print
        print "Guerrier 1: " + str(player1.pv) + " PV, épée longue (1-8 points de dégât), TACO de 20, CA de " + str(player1.ca) + "."
        print "Guerrier 2: " + str(player2.pv) + " PV, épée longue (1-8 points de dégât), TACO de 20, CA de " + str(player2.ca) + "."
        print

    def nouveauCombat(self):
        print ast + "NOUVEAU COMBAT" + ast
        print
        while ((self.player1.pv > 0) and (self.player2.pv > 0)):
            self.cnt = self.cnt + 1
            print ast + "ROUND " + str(self.cnt) + ": INITIATIVE" + ast
            print
            self.calcInitiative()
            print
        print ast + "RESULTAT" + ast
        print
        self.resultat()

    def calcInitiative(self):
        initiative1 = random.randint(1,10)
        initiative2 = random.randint(1,10)
        print "Le guerrier 1 fait son jet d'initiative."
        print str(initiative1) + "!"
        print
        print "Le guerrier 2 fait son jet d'initiative."
        print str(initiative2) + "!"
        print
        if initiative1 == initiative2:
            print "Les deux guerriers attaquent au même moment."
            print
            print ast + "ROUND " + str(self.cnt) + ": ATTAQUE" + ast
            print
            self.attaque(self.player1, self.player2)
            print
            self.attaque(self.player2, self.player1)
        elif initiative1 < initiative2:
            print "Le guerrier 1 attaque en premier."
            print
            print ast + "ROUND " + str(self.cnt) + ": ATTAQUE" + ast
            print
            self.attaque(self.player1, self.player2)
            print
            if self.player2.pv > 0:
                print
                self.attaque(self.player2, self.player1)
        else:
            print "Le guerrier 2 attaque en premier."
            print
            print ast + "ROUND " + str(self.cnt) + ": ATTAQUE" + ast
            print
            self.attaque(self.player2, self.player1)
            print
            if self.player1.pv > 0:
                print
                self.attaque(self.player1, self.player2)

    def attaque(self, player1, player2):
        print "Le guerrier" + str(player1.num) + " fait son jet de toucher."
        print str(player1.d20) + "!"
        if player1.d20 >= player2.ca:
            print "Touché!"
            player2.pv = player2.pv - player1.d8
            print str(player1.d8) + " points de dégât!"
            print "Le guerrier 2 est à " + str(player2.pv) + "/" + str(player2.pvDep) + " PV!"
        else:
            print "Raté!"

    def resultat(self):
        print "Le combat prend fin au round " + str(self.cnt) + "."
        print

        if player1.pv == player1.pvDep:
            print "Le guerrier 1 n'a pas la moindre égratignure."
        elif player1.pv > 0:
            print "Le guerrier 1 est blessé."
        else:
            print "Le guerrier 1 est mort."

        print "Il finit le combat avec " + str(player1.pv) + "/" +str (player1.pvDep) + " PV."
        print

        if player2.pv == player2.pvDep:
            print "Le guerrier 2 n'a pas la moindre égratignure."
        elif player2.pv > 0:
            print "Le guerrier 2 est blessé."
        else:
            print "Le guerrier 2 est mort."

        print "Il finit le combat avec " + str(player2.pv) + "/" +str (player2.pvDep) + " PV."
        print


player1 = Player(1, 10)
player2 = Player(2, 10)
combat = Combat(player1, player2)
combat.intro()
combat.nouveauCombat()
于 2011-08-09T18:43:54.440 に答える
1

デフォルトのグローバル変数は、広く (普遍的に?) 設計上の欠陥と見なされています。「Pythonic」コードを書きたい場合は、グローバル状態をできるだけ少なくするように努力する必要があります。

于 2011-08-09T18:16:08.303 に答える