Python中全局语句的替代品

时间:2013-09-04 17:00:56

标签: python python-2.7

我正在写一个非常简单的轮盘模拟器,只专注于红/黑投注(基本上就像是头或尾的游戏)。

我遇到的问题是跨函数调用变量。

这是代码(我确定它还有其他问题,但我现在关注的是这个问题):

import random

# Defines initial amounts of money and losses
money = 50
losses = 0

# Starts the sim
def roulette_sim():
    print "How much do you want to bet?"
    bet = int(raw_input("> "))   
    if bet > money:
        bet_too_much()
    else:
        red_or_black()


# Prevents one from betting more money than one has
def bet_too_much():
    print "You do not have all that money. Please bet again." 
    raw_input("Press ENTER to continue> ")
    roulette_sim()

# Asks user to select red or black, starts the sim, modifies money/losses
def red_or_black():
    print "OK, you bet %r" %  (bet)
    print "Red or black?"
    answer = raw_input("> ")
    number = random.randint(1, 2)
    if number == 1 and answer == "red":
        print "You win!"
        money += bet
        print "You now have %r money" % (money)
        print "Your losses are %r" % (losses)
        replay()
    elif number == 2 and answer == "black":
        print "You win!"
        money += bet
        print "You now have %r money" % (money)
        print "Your losses are %r" % (losses)
        replay()
    else:
        print "You lost!"
        money -= bet
        losses += bet
        print "You now have %r money" % (money)
        print "Your losses are %r" % (losses)
        replay()

# Asks user whether he/she wants to play again
def replay():
    print "Do you want to play again?"
    play_again = raw_input("y/n> ")
    if play_again == "y":
        roulette_sim()
    else:
        print "OK, bye loser!"


roulette_sim()

所以,我得到了NameError: global name 'bet' is not defined,我可以通过使用global避免这种情况,但我宁愿不诉诸于此。除了使用roulette_sim之外,我如何使用global中的用户在money中为其分配的值来调用此变量?

我认为同样的问题适用于{{1}}变量。

我目前掌握了非常基本的Python知识,所以我为任何错误道歉。

由于

3 个答案:

答案 0 :(得分:4)

使用课程:

import random

class RouletteSim(object):
    def __init__(self):
        # Defines initial amounts of money and losses
        self.money = 50
        self.losses = 0

    # Starts the sim
    def roulette_sim(self):
        print "How much do you want to bet?"
        bet = int(raw_input("> "))
        if bet > self.money:
            self.bet_too_much()
        else:
            self.red_or_black(bet)

    # Prevents one from betting more money than one has
    def bet_too_much(self):
        print "You do not have all that money. Please bet again."
        raw_input("Press ENTER to continue> ")
        self.roulette_sim()

    # Asks user to select red or black, starts the sim, modifies money/losses
    def red_or_black(self, bet):
        print "OK, you bet %r" %  (bet)
        print "Red or black?"
        answer = raw_input("> ")
        number = random.randint(1, 2)
        if number == 1 and answer == "red":
            print "You win!"
            self.money += bet
            print "You now have %r money" % (self.money)
            print "Your losses are %r" % (self.losses)
            self.replay()
        elif number == 2 and answer == "black":
            print "You win!"
            self.money += bet
            print "You now have %r money" % (self.money)
            print "Your losses are %r" % (self.losses)
            self.replay()
        else:
            print "You lost!"
            self.money -= bet
            self.losses += bet
            print "You now have %r money" % (self.money)
            print "Your losses are %r" % (self.losses)
            self.replay()

    # Asks user whether he/she wants to play again
    def replay(self):
        print "Do you want to play again?"
        play_again = raw_input("y/n> ")
        if play_again == "y":
            self.roulette_sim()
        else:
            print "OK, bye loser!"

RouletteSim().roulette_sim()

答案 1 :(得分:2)

您可以将值作为参数传递给函数,并使函数返回更新的值,例如:

def roulette_sim(money, losses):
    print "How much do you want to bet?"
    bet = int(raw_input("> "))   
    if bet > money:
        return bet_too_much(money, losses)
    else:
        eturn red_or_black(money, losses, bet)

red_or_black而不是修改全局moneylosses变量的情况下,它会将丢失的moey数量传递给replay,并使用更新的值调用roulette_sim

或者,您可以简单地将所有内容放入一个类中,并使用self.moneyself.lossesself.bet作为“全局”。

然而您可能会注意到这些功能的整体设计糟糕。 他们有复杂的关系,他们使用递归,这意味着在(可能少于)1000次投注之后,你将获得RuntimError: Maximum recursion depth exceeded

您可以重构整个代码以使用循环。 只是提出一个想法:

import random



def get_bet():
    bet = float('+inf')
    while bet > money:
        print("How much do you want to bet?")
        bet = int(raw_input("> "))
        if bet > money:
            bet_too_much()
    return bet

def bet_too_much():
    print("you do not have all the money. Please bet again.")
    raw_input("Press ENTER to continue")


def roulette_sim():
    money = 50
    losses = 0
    while True:
        bet = get_bet()
        won = red_or_black(bet)
        money += won
        losses -= won

注意:想象一下,你想要写一个玩家下注的不同游戏。 使用你的设计,真的 hacky重新使用这个新游戏中的功能。

通过上述设计,您可以自由地重复使用get_bet()功能,向玩家询问赌注等。 这只是为了给出使用循环而不是将函数与递归循环紧密耦合的另一个原因。

答案 2 :(得分:1)

bet是roulette_sim函数中的有效变量 但是在red_or_black函数中,你首先在

开始使用它
print "OK, you bet %r" %  (bet)

然后

money += bet

等无效的,您应该将您的赌注作为参数传递给red_or_black 调用该函数如下:

red_or_black(bet)   # bet is argument

并将其定义为:

def red_or_black(bet):   # bet is parameter

一切都会好的