0

我是 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 = []

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

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

class line :
    name = "abc"

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

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

但是上面的代码输出"abc"

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

4

3 回答 3

2

第一种语法:

class line :
    points = []

创建points一个属性。因此,它将在类的所有实例之间共享。

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

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

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

于 2012-08-29T11:04:19.597 回答
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]
于 2012-08-29T11:04:23.040 回答
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确实创建了一个新的实例属性,而类属性保持不变。正如changename从未调用过的那样line1,对其的引用name将解析为line类属性。

于 2012-08-29T11:20:20.460 回答