python:修改参数而不创建新对象

python:修改参数而不创建新对象,python,function,scope,Python,Function,Scope,我希望games在调用check()时更新,但只要运行'games+=1',它就会创建一个新对象(一个python怪癖),而不是修改参数。但是我想修改参数,那么我该怎么做呢 现在赢了和游戏在check()返回后重置为0 def检查(…游戏,胜利,…): ... 游戏+=1 wins+=1,如果winner==“代理”\ 如果获胜者=='bot'\ 其他0.5 ... 返回1 返回0 def play_bot(): 游戏=0 wins=0 ... 如果检查(…游戏,赢,…):玩家=选择([0,1

我希望
games
在调用
check()
时更新,但只要运行'games+=1',它就会创建一个新对象(一个python怪癖),而不是修改参数。但是我想修改参数,那么我该怎么做呢

现在
赢了
游戏
在check()返回后重置为0


def检查(…游戏,胜利,…):
...
游戏+=1
wins+=1,如果winner==“代理”\
如果获胜者=='bot'\
其他0.5
...
返回1
返回0
def play_bot():
游戏=0
wins=0
...
如果检查(…游戏,赢,…):玩家=选择([0,1])
...

我已经找到了python创建新对象的原因,但没有一个干净的方法来防止这种情况

我不是python专家,但我相信python有不变和可变的类型。当在函数中修改不可变类型时,将创建对象的新实例。不可变类型是字符串、元组和数字等。在您的情况下,
games
,是一个不可变的类型(数字)

请参见:


我不知道如何避免不可变类型的新对象创建。最明显的解决方案是,使用全局变量或返回新的games对象。

这可能是重复的。我建议你仔细检查一下这个问题

python还允许您返回多个值。你能行

return 1, games


通过这样做,您将得到一个元组,其中包含从函数返回的两个元素。所以你不能直接在if语句中使用它。您可以存储这两个值,然后在if语句中进行比较。

最干净的方法是从
检查功能返回所需的信息:

def check(node, winner):
    if node:
        return 1 if winner == 'agent' else 0 if winner == 'bot' else 0.5
    # Return None by default.

def play_bot():
    games = 0
    wins = 0
    win = check(node, winner)
    if win is not None:
        games += 1
        wins += win
        player = choice([0,1])
如果确实需要执行OOP路线,可以将对象传递给
check
,以便函数可以根据需要对其进行修改:

class Record:
    def __init__(self):
        self.games = self.wins = 0

def check(node, record, winner):
    if node:
        record.games += 1
        record.wins += 1 if winner == 'agent' else 0 if winner == 'bot' else 0.5
        return True
    return False

def play_bot():
    record = Record()
    if check(node, record, winner):
        player = choice([0,1])

第三种解决方案是使用全局变量,但我真的不建议这样做。它们可能真是一团糟。

数字是不可更改的类型。游戏是函数中参数游戏的副本。所以你不能改变它


如果你想改变它,你可以把它放在一个可变变量中,例如列表,字典。然后您可以在函数中更改它。

games
内部
检查
是局部变量,与外部变量
games
无关-它们的名称相同,但python有两个不同的变量。为什么返回1或0而不是新值?这些应该是错误代码吗?如果是这样的话,你应该考虑改变你的体系结构——你似乎在编写适合C语言的代码来对抗语言。在你的评论中,我看到了“面向对象的封装”。你创建类吗?然后你可以使用
self.
来解决问题
int
s是不可变的实际上,这里讨论的作用域机制是非常通用的。函数不能赋值给参数变量,因为参数可以是任何表达式,而不仅仅是变量。谢谢,这将非常有用。虽然返回对象是一种选择,但它会破坏面向对象的封装。
class Record:
    def __init__(self):
        self.games = self.wins = 0

def check(node, record, winner):
    if node:
        record.games += 1
        record.wins += 1 if winner == 'agent' else 0 if winner == 'bot' else 0.5
        return True
    return False

def play_bot():
    record = Record()
    if check(node, record, winner):
        player = choice([0,1])