理解应该绑定到对象实例的类范围的变量

yay*_*ayu 2 python oop

这是一个为玩家分配符号的类。它应该接受一个移动并将该移动添加到玩家现有的移动存储库中。

class Player:
   ...:     positions = []
   ...:     def __init__(self,symbol):
   ...:         self.symbol = symbol
   ...:     def move(self,position):
   ...:         self.position = position
   ...:         self.positions.append(self.position)
Run Code Online (Sandbox Code Playgroud)

我的问题是位置的行为是“全局”的,因为它不与对象实例绑定,以证明:

>>>a = Player('x')
>>>b = Player('y')
>>>a.move(1)
>>>b.positions
[1]
Run Code Online (Sandbox Code Playgroud)

the*_*eye 6

当你说,

class Player:
    positions = []
Run Code Online (Sandbox Code Playgroud)

positions将是一个类变量,并且该类的所有实例都使用同一个对象。你可以通过这个确认

player1, player2 = Player(), Player()
print player1.positions is player2.positions    # True
print Player.positions is player1.positions     # True
Run Code Online (Sandbox Code Playgroud)

如果您想创建实例变量(positions为 的每个实例创建单独的变量Player),您可以在__init__函数中创建它。它是一个特殊的初始化函数,它获取当前实际对象作为第一个参数。您可以positions像这样创建变量并将其附加到该对象

class Player:
    def __init__(self):
        self.positions = []

player1, player2 = Player(), Player()
print player1.positions is player2.positions    # False
Run Code Online (Sandbox Code Playgroud)

在这里,self指的是新构造的对象,您正在该对象中创建一个新变量,self.positions并且您正在使用空列表对其进行初始化

self.positions = []
Run Code Online (Sandbox Code Playgroud)

因此,每当您创建 的新实例时Playerself将指代创建的新实例,并且positions将在每个实例上创建新变量,这意味着每个实例都有单独的positions变量。

并且无论何时move被调用,您都不必在 上创建新position变量self。相反,你可以这样做

def move(self, position):
    self.positions.append(position)
Run Code Online (Sandbox Code Playgroud)

如果您使用的是 Python 2.x,最好使用新的样式类,如下所示

class Player(object):
    def __init__(self):
        self.positions = []
Run Code Online (Sandbox Code Playgroud)