1

在上一篇文章中,有人告诉我我正在使用 Python 进行编码,就像在 BASIC 中一样(我还没有在 Python 中“思考”)。这可能是真的,这就是我需要帮助的原因。话虽这么说,到目前为止我已经阅读了一本关于 Python 的书(Bytes of Python),我在网上又买了两本书(其中一本是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 教程都应该教你所有这些东西。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 回答
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 回答
1

默认情况下,全局变量被广泛(普遍?)认为是设计缺陷。如果你想编写“Pythonic”代码,你应该努力拥有尽可能少的全局状态。

于 2011-08-09T18:16:08.303 回答