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

发布于 2024-11-28 14:23:54 字数 4875 浏览 6 评论 0原文

在上一篇文章中,我被告知我正在使用 Python 进行编码,就像使用 BASIC 进行编码一样(我还没有使用 Python 进行“思考”)。这可能是真的,这就是我需要帮助的原因。话虽这么说,到目前为止我已经读了一本关于 Python 的书(Bytes of 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()

In a previous post, I was told I am coding in Python like you would in BASIC (I am not "thinking" in Python yet). This is probably true and this is why I need help. This being said, I have read one book about Python so far (Bytes of Python), I bought two more books online (one of which is Invent with Python, which I am reading) and I did many tutorials from The New Boston. Still, my question might sound newbie-ish to you.

In FreeBasic, variables are all globalized. In Python, I have to globalize them for every single new function I create. This isn't very practical. So what am I expected to do? How would a "native Python speaker" tackle this problem? Below you'll find a small program I have created where I globalize in all my variables inside functions.

#-*- 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()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

メ斷腸人バ 2024-12-05 14:23:54

除非要分配名称,否则不需要将名称声明为全局名称。

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

You don't need to declare a name as global unless you are going to assign to it.

a = 1
b = 2
def foo():
    global b
    print a # prints 1
    b = 3
foo()
print b # prints 3
日暮斜阳 2024-12-05 14:23:54

我重新组织了您的程序,向您展示面向对象编程的基础知识。您需要了解类和对象。您还应该查看字符串格式,了解将字符串组合在一起的正确方法。

基本上,您创建两个玩家对象,然后为这两个玩家创建一个战斗对象。然后,您在战斗对象上调用方法以实际进行战斗。 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()

I've reorganized your program to show you the basics of object oriented programming. You need to learn about classes and objects. You should also look at string formatting for the right way to put strings together.

Basically, you create two player objects, and then create a combat object for those two players. Then, you call methods on the combat object in order to actually do the combat. self is how an instance of a class refers to itself. Any good Python tutorial should teach you about all of these things.

The only remaining global variable is a constant, ast. Global constants can occasionally be OK.

#-*- 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()
翻了热茶 2024-12-05 14:23:54

在 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)

总之,您几乎从不需要全局变量,但在许多情况下,您需要一些非全局变量。

In python, as in many modern languages, prolific use of global variables is considered an anti-pattern. There are lots of reasons why:

  • it obstructs function reentrancy, which is important for efficient multi-threaded code.
  • it makes unit testing harder, which is helpful on medium to large projects
  • it makes modules more interdependent, which makes it harder to track down problems and to fix them once they are found.

You should endevor to pass the data each function needs:

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

def baz(bar):
    print bar

If you need to capture state from one function to the next, you can wrap that into a class.

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)

In summary, You almost never need globals, but in many cases, you need to have something that is not global.

等待我真够勒 2024-12-05 14:23:54

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

Global variables by default are widely (universally?) considered a design flaw. If you want to write "Pythonic" code, you should strive to have the smallest possible amount of global state.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文