Python 为什么要换班';s属性会导致不同的结果?

Python 为什么要换班';s属性会导致不同的结果?,python,class,attributes,Python,Class,Attributes,我创建了一张具有属性suitList和编号的班级卡。当我同时更改它们时,我希望它不会影响不同的对象。然而,结果令人困惑。为什么更改suitelist会影响其他对象的suitelist?请解释一下 class Card: suitList = ["CLubs"] number = 1 def __init__ (self, rank = 0): self.rank = rank def __str__ (self): return (self.suitL

我创建了一张具有属性
suitList
和编号的班级卡。当我同时更改它们时,我希望它不会影响不同的对象。然而,结果令人困惑。为什么更改
suitelist
会影响其他对象的
suitelist
?请解释一下

class Card:
  suitList = ["CLubs"]
  number = 1

  def __init__ (self, rank = 0):
      self.rank = rank

  def __str__ (self):
      return (self.suitList[self.rank] + "  " + str(self.number) + ";\n")
c1 = Card()
c2 = Card()
print c1
c1.suitList[0] = "Heart"
c1.number = 3
print c1
print c2
c3 = Card()
print c3

这是因为您已将
suitList
设置为类属性,该属性在类的所有实例中共享。如果希望每个实例都有一个唯一的
suitList
列表,则应将其作为实例属性:

def __init__(self, rank = 0):
     self.rank = rank
     self.suitList = ["CLubs"]
     self.number = 1
您可能还希望将
number
的定义移动到
\uuuu init\uuuu
方法中,使其也成为实例属性:

def __init__(self, rank = 0):
     self.rank = rank
     self.suitList = ["CLubs"]
     self.number = 1
有关这方面的更多信息,请参阅


另外,您会注意到,我在所有名称前面加了
self。
您需要这样做,以便使值成为类的属性。如果我们这样做了:

def __init__(self, rank = 0):
     self.rank = rank
     suitList = ["CLubs"]
     number = 1

suitelist
number
将被设置为
\uuuu init\uuu
方法的本地属性。

这是因为您已将
suitelist
设置为类属性,该属性在类的所有实例之间共享。如果希望每个实例都有一个唯一的
suitList
列表,则应将其作为实例属性:

def __init__(self, rank = 0):
     self.rank = rank
     self.suitList = ["CLubs"]
     self.number = 1
您可能还希望将
number
的定义移动到
\uuuu init\uuuu
方法中,使其也成为实例属性:

def __init__(self, rank = 0):
     self.rank = rank
     self.suitList = ["CLubs"]
     self.number = 1
有关这方面的更多信息,请参阅


另外,您会注意到,我在所有名称前面加了
self。
您需要这样做,以便使值成为类的属性。如果我们这样做了:

def __init__(self, rank = 0):
     self.rank = rank
     suitList = ["CLubs"]
     number = 1
suitList
number
将成为
\uuuu init\uuuu
方法的本地属性。

这两个属性是类属性或。如果要声明非静态属性,则必须在变量名称前面加上
self
,这表示正在使用的类的当前实例:

class MyClass:
    def __init__(self):
        self.suitList = ["CLubs"]
        self.number = 1
有关什么是
self
以及静态和非静态类变量之间的差异的更多信息:

  • 这两个属性是类属性或。如果要声明非静态属性,则必须在变量名称前面加上
    self
    ,这表示正在使用的类的当前实例:

    class MyClass:
        def __init__(self):
            self.suitList = ["CLubs"]
            self.number = 1
    
    有关什么是
    self
    以及静态和非静态类变量之间的差异的更多信息:


  • 如前所述,您正在混淆类属性和实例属性

    在您的示例中,suitList和number是类属性,它们在所有实例(c1、c2、c3)中共享 在
    c1.suitList[0]=“Heart”
    中更改类属性时,它将反映在所有类实例中

    要解决这个问题,你有一些选择:我给你两个

    1) 仅使用实例属性: 在这种情况下,没有class属性,要更改卡套件,可以使用c1.suit直接分配它

    2) 混合使用类/属性: 在本例中,Rank是在SuiteList中查找的索引。要更改卡片套装,您需要更改其等级,而不是列表

    两个示例输出:

    Heart 3
    CLubs 0
    

    如前所述,您正在混淆类属性和实例属性

    在您的示例中,suitList和number是类属性,它们在所有实例(c1、c2、c3)中共享 在
    c1.suitList[0]=“Heart”
    中更改类属性时,它将反映在所有类实例中

    要解决这个问题,你有一些选择:我给你两个

    1) 仅使用实例属性: 在这种情况下,没有class属性,要更改卡套件,可以使用c1.suit直接分配它

    2) 混合使用类/属性: 在本例中,Rank是在SuiteList中查找的索引。要更改卡片套装,您需要更改其等级,而不是列表

    两个示例输出:

    Heart 3
    CLubs 0
    

    编号是类属性吗?是的,
    number
    也是类属性,将在所有实例之间共享。如果您希望每个实例都是唯一的,请将其定义移动到
    \uuuu init\uuuu
    中。好的,您说数字也是属性,由所有实例共享。在我的示例中,我将number的值更改为3,并希望所有实例都将number的值更改为3。然而,只有c1的编号发生了变化。您能解释一下原因吗?因为当您执行
    c1.number=3
    时,您在
    c1
    上创建了一个名为
    number
    的新实例属性,并将其值设置为
    3
    。然而,
    number
    class属性被遮住了。对不起,我还是有点困惑。number和SuiteList都是类属性,应该具有相同的行为,对吗?您说更改c1.SuiteList[0]会更改所有其他实例的SuiteList,而更改c1.number不会更改,您的解释是number属性被遮住了。你的意思是这样的行为不仅与属性是否为class属性有关,还与属性本身的类型有关?number是class属性吗?是的,
    number
    也是class属性,将在所有实例中共享。如果您希望每个实例都是唯一的,请将其定义移动到
    \uuuu init\uuuu
    中。好的,您说数字也是属性,由所有实例共享。在我的示例中,我将number的值更改为3,并希望所有实例都将number的值更改为3。然而,只有c1的编号发生了变化。您能解释一下原因吗?因为当您执行
    c1.number=3
    时,您在
    c1
    上创建了一个名为
    number
    的新实例属性,并将其值设置为
    3
    。然而,
    number
    class属性被遮住了。对不起,我还是有点困惑。