python类属性和实例属性_python中的类属性和实例属性

面向对象语言中,一般会有“静态变量”,也就是给整个类共享的变量,如C++,java中static修饰的变量。但是在 python 中并没有 static 这个关键字,实现类似功能需要依靠python中的类属性和实例属性的语法特点。本文主要就是讲述这两种属性的区别。

在讲述之前,需要清楚下面两个事实:

1)python 中类创建的对象叫实例

2)类和实例均是对象,均有自己的对象属性,可通过__dict__查看

下面先看一个例子:

1

2

3

4

5

6

7

8

9

10

11class TestAttribute:

content = []

def addContent(self,x):

self.content.append(x)

if __name__ == '__main__':

t1 = TestAttribute()

t2 = TestAttribute()

t1.addContent('t1')

print 'object t1:', t1.content, t1.__dict__

print 'object t2:', t2.content, t2.__dict__

输出结果:

1

2object t1: ['t1'] {}

object t2: ['t1'] {}

从例子可以看到,这时的 content 就相当于一个static 变量,被所有实例共享。注意后面那个花括号{}表示实例的所有对象属性,只是当前实例没有自己的属性。

那假如各个实例要有自己独立的变量的?也很简单,只需要在类的构造函数(也就是__init__函数)为变量赋值即可.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15class TestAttribute:

content = []

def __init__(self):

self.content=[]

def addContent(self,x):

self.content.append(x)

if __name__ == '__main__':

t1 = TestAttribute()

t2 = TestAttribute()

t1.addContent('t1')

print 'object t1:', t1.content ,t1.__dict__

print 'object t2:', t2.content ,t2.__dict__

输出的结果如下所示:

1

2object t1: ['t1'] {'content':['t1']}

object t2: [] {'content':[]}

从结果可知,现在的t1,t2的变量独立了。那原因是什么呢?

原因是Python中对象属性的获取是按照从下到上的顺序来查找属性

怎么理解上面这句话呢?以上面代码为例,类和实例的关系如下所示:

1

2

3

4TestAttribute

____|____

| |

t1 t2

输出t1.content时,python 解析器会先查看对象 t1 中是否有content这个属性,有的话输出这个属性的值,没有的话就往上查找 TestAttribute 中是否有这个属性并输出。

在上面的例一中,因为t1和t2的属性均为空,所以输出 t1.content 和 t2.content时实际上是输出 TestAttribute 的属性。又因为 TestAttribute 的 content 属性被修改了 t1 修改了,所以最后输出的的 t1.content 和 t2.content 内容一致。

而在例二中,因为在构造函数中的为content复制的操作使得每个被创建的实例均有自己的content属性,所以 t1 修改 content 时查到自己有content的属性,就只会修改自己的 content。不影响t2 的 content 和 TestAttribute 的 content。这个可以从下面的例子看出,假如将例二的代码修改成如下所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17class TestAttribute:

content = []

def __init__(self):

self.content=[]

def addContent(self,x):

self.content.append(x)

if __name__ == '__main__':

t1 = TestAttribute()

t2 = TestAttribute()

t1.addContent('t1')

TestAttribute.content.append('tt')

print 'object t1:', t1.content ,t1.__dict__

print 'object t2:', t2.content ,t2.__dict__

print 'class TestAttribute:', TestAttribute.content

那输出结果是:

1

2

3object t1: ['t1'] {'content':['t1']}

object t2: [] {'content':[]}

class TestAttribute: ['tt']

可以看到这三个对象的属性均独立。

那么如何为一个实例添加属性呢?

答案是通过赋值号 = 给实例所需添加的属性赋值。 通过赋值号 = 给实例所需添加的属性赋值实际上是将这个属性指向了新的引用,也就是新的内存空间。

如在例一中没有通过赋值号为 content 赋值,所以这个属性并没有成为 t1 自己的属性,输出t1.__dict__ 为空。而在例二中的构造函数里面为每个实例的content均赋值,所以例二中的三个对象的content属性独立。通过下面的例子可以更深入说明这点:

1

2

3

4

5

6

7

8

9

10class TestAttribute:

num = 0

if __name__ == '__main__':

t1 = TestAttribute()

t2 = TestAttribute()

t1.num = 1

print 'object t1:', t1.num, t1.__dict__

print 'object t2:', t2.num, t2.__dict__

输出结果:

1

2object t1: 1 {'num': 1}

object t2: 0 {}

最后,小结如下:

1.Python中的类和实例是两个完全独立的对象;

2.Python中属性的获取是按照从下到上的顺序来查找属性;

3.为实例添加属性的方法:通过赋值号 = 给实例所需添加的属性赋值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值