我是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"
所以我不明白为什么同类型的声明因类型而异。
答案 0 :(得分:2)
第一种语法:
class line :
points = []
使points
成为类属性。因此,它将在该类的所有实例之间共享。
要确保属性属于某个类,您应该执行以下操作:
class line(object) :
def __init__(self):
self.points = []
即,在创建新实例时,仅在__init__
中创建属性。
答案 1 :(得分:2)
因为在这种情况下
class line :
points = []
points
是类成员。它属于该类,由于line1
和line2
具有相同的类,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
类属性。