将程序从FreeBASIC转换为Python:全局化变量

时间:2011-08-09 18:09:58

标签: python oop global-variables freebasic

在上一篇文章中,我被告知我在Python中编码就像你在BASIC中编写的那样(我还没有在Python中“思考”)。这可能是真的,这就是我需要帮助的原因。话虽这么说,到目前为止我已经阅读了一本关于Python的书( Python的字节),我在网上买了两本书(其中一本是 Invent with Python ,我是我正在阅读)我从新波士顿做过很多教程。不过,我的问题对你来说可能听起来很新鲜。

在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 个答案:

答案 0 :(得分:3)

除非您要指定名称,否则无需将名称声明为全局名称。

a = 1
b = 2
def foo():
    global b
    print a # prints 1
    b = 3
foo()
print b # prints 3

答案 1 :(得分:2)

我重新组织了您的计划,向您展示object oriented programming的基础知识。您需要了解类和对象。您还应该查看string formatting以便将字符串放在一起的正确方法。

基本上,您创建两个玩家对象,然后为这两个玩家创建一个战斗对象。然后,您在战斗对象上调用方法以实际进行战斗。 self实例引用自身的方式。任何好的Python教程都应该教你所有这些事情。

唯一剩下的全局变量是常量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()

答案 2 :(得分: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)

总之,你几乎从不需要全局变量,但在很多情况下,你需要拥有全局的东西。

答案 3 :(得分:1)

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