如何在类中声明'list'的成员?

时间:2012-08-29 11:01:14

标签: python

我是python的新手,它让我很困惑。

我想写点像

class line :
    points = []

    def add(self, point) :
        self.points.append(point)

line1 = line()
line2 = line()
line1.add("Some point")
print line2.points

输出:['Some point']

结果就像他们引用相同的列表一样 但我确实希望对象成员不是类成员。

我试过,如果points是int,或者其他简单类型,它可以正常工作。

此外,我知道如果我写

def __init__(self) :
    self.points = []

它也可以工作,但我不明白为什么他们默认指向同一个列表。

PS。我知道写一个init会起作用。

class line :
    name = "abc"

    def changename(self, name) :
        self.name = name

line1 = line()
line2 = line()
line1.changename(123)
print line2.name

但上面的代码输出"abc"

所以我不明白为什么同类型的声明因类型而异。

3 个答案:

答案 0 :(得分:2)

第一种语法:

class line :
    points = []

使points成为属性。因此,它将在该类的所有实例之间共享。

要确保属性属于某个类,您应该执行以下操作:

class line(object) :
    def __init__(self):
        self.points = []

即,在创建新实例时,仅在__init__中创建属性。

答案 1 :(得分:2)

因为在这种情况下

class line :
    points = []

points成员。它属于该类,由于line1line2具有相同的points是相同的列表。

所以你正确使用

def __init__(self) :
    self.points = []

而是创建一个与实例绑定的实例成员,而不是类。

回答您的修改

如果你写:

def changename(self, name) :
    self.name = name

您使用self.name = name覆盖您的类成员并创建新的实例成员

回到第一个例子,就像写作:

def add(self, point) :
    self.points = self.points + [point]

答案 2 :(得分:1)

正如其他人已经解释的那样,并且您显然已经理解,以下内容创建了一个属性,由每个实例共享:

class line:
    points = []

当您在代码中引用此属性时,Python会尝试将其作为当前作用域,然后按照封闭的作用域进行操作。因此,如果您致电self.points.append(),则确实正在更改points 属性。

当您在代码中分配self.points时,您正在定义 points 实例属性。因此,在第二个示例中points是一个字符串时,changename函数实际上在调用时会创建一个新的实例属性。

您可以尝试以下操作:

print line.name  # prints the class attribute
print line1.name # prints the class attribute
print line2.name # prints the instance attribute

您会注意到调用changename确实创建了一个新的实例属性,而class属性保持不变。由于changename从未调用line1,因此对其name的引用将解析为line类属性。