为什么更改类的属性会导致不同的结果?

2024-04-29 01:59:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我创建了一个类卡片,带有属性suitList和数字。当我同时更改它们时,我希望它不会影响不同的对象。然而,结果令人困惑。为什么更改suitList会影响其他对象suitList?请解释一下。你知道吗

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

Tags: 对象selfnumber属性def数字cardclass
3条回答

这是因为您已经创建了suitList一个类属性,它在类的所有实例中共享。如果您希望每个实例都有一个唯一的suitList列表,那么应该将其设置为实例属性

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

您可能还希望将number的定义移到__init__方法中,以便它也成为实例属性:

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

有关这方面的详细信息,请参见Python: Difference between class and instance attributes


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

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

suitListnumber将成为__init__方法的局部。你知道吗

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

class MyClass:
    def __init__(self):
        self.suitList = ["CLubs"]
        self.number = 1

有关什么是self以及静态类变量和非静态类变量之间的差异的更多信息:

  1. Python __init__ and self what do they do?

  2. Python 'self' keyword

  3. Explaining the python 'self' variable to a beginner

  4. What is the purpose of self?

  5. https://stackoverflow.com/questions/3332454/oop-python-oriented-tutorials

  6. Python: Difference between class and instance attributes

如前所述,将类属性与实例属性混淆。你知道吗

在您的示例中,suitList和number是class属性,它们在所有实例(c1、c2、c3)中共享 当您在c1.suitList[0] = "Heart"中更改类属性时,它将反映在所有类实例中。你知道吗

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

1) 仅使用实例属性:

class Card:
    def __init__(self,number=0,suit="CLubs"):
        self.number = number
        self.suit = suit

    def __str__(self):
        return "%s %d"%(self.suit,self.number)

c1 = Card()
c2 = Card()
c1.suit = "Heart"
c1.number = 3
print c1
print c2

在本例中,没有class属性,要更改卡套件,可以使用c1.suit直接分配它。你知道吗

2) 混合使用类/属性:

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

    def __str__(self):
        return (Card.suitList[self.rank] + "  " + str(self.number))

c1 = Card()
c2 = Card()
c1.rank = 1
c1.number = 3
print c1
print c2

在本例中,Rank是在suitList中查找的索引。要更改卡片的套装,您需要更改它的等级,而不是列表。你知道吗

两个示例输出:

Heart 3
CLubs 0

相关问题 更多 >