python类实例变量和类变量

我在理解类/实例变量如何在Python中工作时遇到问题。我不明白为什么当我尝试这段代码时列表变量似乎是一个类变量


class testClass():

    list = []

    def __init__(self):

        self.list.append('thing')


p = testClass()

print p.list


f = testClass()

print f.list

输出:


['thing']

['thing', 'thing']

当我这样做时,它似乎是一个实例变量


class testClass():

    def __init__(self):

        self.list = []

        self.list.append('thing')


p = testClass()

print p.list


f = testClass()

print f.list

输出:


['thing']

['thing']


慕码人8056858
浏览 495回答 3
3回答

慕容森

这是因为Python使用.。解析名称的方式。在编写时self.list,Python运行时首先尝试list通过在实例对象中查找名称来解析名称,如果找不到,则在类实例中进行查找。让我们逐步研究它self.list.append(1)list对象中有名称self吗?是的:使用它!完。否:转到2。list对象的类实例中是否有名称self?是的:使用它!完否:错误!但是,当您绑定名称时,情况有所不同:self.list = []list对象中有名称self吗?是:覆盖它!否:绑定!因此,这始终是一个实例变量。您的第一个示例list在类实例中创建一个,因为这是当时的活动范围(没有self任何地方)。但是您的第二个示例list在的范围内显式创建了一个self。这个例子更有趣:class testClass():    list = ['foo']    def __init__(self):        self.list = []        self.list.append('thing')x = testClass()print x.listprint testClass.listdel x.listprint x.list那将打印:['thing']['foo']['foo']删除实例名称后,可以通过self引用看到类名称。

HUX布斯

Python有关于查找名称的有趣规则。如果您真的想改变主意,请尝试以下代码:class testClass():    l = []    def __init__(self):        self.l = ['fred']这将给每个实例一个变量l,该变量将屏蔽类变量l。如果这样做,您仍然可以使用class变量self.__class__.l。我的想法是……只要您这样做instance.variable(即使对于方法名,它们只是值恰好是函数的变量),它都会在实例的字典中查找它。如果找不到它,它将尝试在实例的“类”字典中查找它。仅当变量被“读取”时。如果将其分配给它,它将始终在实例字典中创建一个新条目。

守着一只汪

在第一个示例中,list是类的一个属性,由该类的所有实例共享。这意味着您甚至可以在没有类型对象的情况下访问它testClass:>>> class testClass():...     list = []...     def __init__(self):...             self.list.append("thing")... >>> testClass.list[]>>> testClass.list.append(1)>>> testClass.list[1]但是所有对象都list与该类以及彼此共享该属性:>>> testObject = testClass()>>> testObject.list[1, 'thing']>>> testClass.list[1, 'thing']>>> >>> testObject2 = testClass()>>> testClass.list[1, 'thing', 'thing']>>> testObject2.list[1, 'thing', 'thing']
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python