学完了面向对象的三大特性,已经get了所有屌丝技能的我们也当一回文艺小青年,来看看类的成员和成员修饰符。
今天‘三’这个数字好亲和~~~类成员可以分为三类:字段、方法和属性
一、字段
首先我们来看看字段,先上图:
我们看上面左侧这张图,第二个黄框框里面的字段我们见过的,以前也一直是这么用的,我们叫它普通字段,在使用的时候我们使用 对象名.字段名 的方法就可以调用,那么第一个的黄框框里的静态字段又是怎么一回事呢?我们可以看出,它是一个属于类的变量,并不是只属于一个对象,而是属于一个类,那么静态字段和普通字段在实际意义上有什么区别呢?我们来看旁边的例子。中间的图是我们调用左边类中变量的代码,右边是执行结果,首先普通字段的使用方式和以前一样,而静态字段,我们发现他有两种调用方式:
一、对象名.字段名 二、类名.字段名。从上例中我们可以看出,使用 对象名.字段名 的方法对字段的值进行修改,我们只是修改了该对象的字段内容,并不会影响其他对象及类变量本身,如果使用 类名.字段名 的方式进行修改,则只是修改了该类的字段内容,其他对象不会受到影响。
我们从内存的角度来看这个问题,当我们使用类名.字段名去调用静态变量的时候,这个变量是存在类的内存中的,这个时候各个对象都可以取到类的内存中的变量,但是当我们使用对象名.字段名去修改这个静态变量的时候,我们其实是在对象的内存中又开辟了一块空间去存储这个字段和修改后的值,所以一个对象的字段发生改变,类和其他对象的该字段并不会发生变化。哎呦,总之解决这个问题的最终办法就是始终用 类名.字段名 去使用类中的静态变量就对了!
1 #!/usr/bin/env python 2 #-*-coding:utf-8-*- 3 class father(object): 4 5 #静态字段 6 money = 10000 7 def __init__(self,name,salary): 8 9 #普通字段 10 self.name = name 11 self.salary = salary 12 13 14 dad1 = father('dad1',6000) 15 dad2 = father('dad2',7000) 16 17 dad1.salary += 1000 18 dad2.salary += 1000 19 print 'dad1.salary:',dad1.salary 20 print 'dad1.salary:',dad2.salary 21 print '*'*20 22 dad1.money += 1000 23 dad2.money += 1000 24 print 'father.money : ',father.money 25 print 'dad1.money : ',dad1.money 26 print 'dad2.money : ',dad2.money 27 print '*'*20 28 father.money += 1000 29 print 'father.money : ',father.money 30 print 'dad1.money : ',dad1.money 31 print 'dad2.money : ',dad2.money
二、方法
方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于定义和调用的方式不同。
- 普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;
- 类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;
- 静态方法:由类调用;无默认参数;
我们看上面的两张图,实现的是同样的功能,左图是使用普通方法,右图则使用了类方法和静态方法,我们可以发现,这两个方法中都没有使用到对象本来的属性,这个时候如果还需要再给类进行初始化然后再用 对象名.方法名 的方法去进行调用,就会显得非常繁琐了,这个时候我们就可以使用类变量和静态变量来完成,只要加上@classmethod或@staticmethod修饰符,就可以将普通方法变成类方法或者静态方法。需要注意的是:类方法至少有一个参数,那就是这个类本身,用cls表示,不要问为什么,背下来就好。。。而静态方法不需要传对象也不需要传类参数,就像个普通的函数一样用就对了!这两个方法都是用 类名.方法名来调用,所以自然地也就可以使用 类变量,但是却不能访问对象的变量,原因你懂的,因为他根本就没有接收到对象参数,所以也就找不到对象中的内容啦~
三、属性
如果你已经了解Python类中的方法,那么属性就非常简单了,因为Python中的属性其实是普通方法的变种。
哎,其实就是这样,我们看一下当我们想查看税后工资的时候,这其实是一个人的属性,但是它却要经过一些特殊的处理或者计算,让我们必须写在一个方法里,这个时候我们使用@property这个修饰符,就可以像使用字段一样调用这个方法了。对,属性是处女座就是这么矫情!!!当然如果你和我一样是神经大条的射手座,完全不用care这个属性什么鬼的。
尽管如此,在这里还是要说一说要注意一下几点:
1.定义时,在普通方法的基础上添加 @property 装饰器;
2.定义时,属性仅有一个self参数
3.调用时,无需括号
未完。。。
参考:http://www.cnblogs.com/wupeiqi/articles/5017742.html
1 #!/usr/bin/env python 2 #-*-coding:utf-8-*- 3 class father(object): 4 5 #静态字段 6 money = 10000 7 def __init__(self,name,salary): 8 9 #普通字段 10 self.name = name 11 self.salary = salary 12 13 @property 14 def Net_pay(self): 15 '''属性''' 16 netPay = self.salary - ((self.salary- 3500)*0.1) 17 return netPay 18 19 dad1 = father('dad1',6000) 20 print dad1.Net_pay