类成员
类成员分为三大类:字段、方法、属性
注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段。而其他的成员,则都是保存在类中,即:无论对象的多少,在内存中只创建一份。
字段
- 普通字段:属于对象
- 静态字段:属于类
1 #!/usr/bin/env python 2 #coding=utf-8 3 __author__ = 'yinjia' 4 5 6 class Provice: 7 #静态字段 8 country = "中国" 9 10 def __init__(self,name):11 temp = "xxx"12 #普通字段,在对象中13 self.name = name14 15 #访问普通字段16 sz = Provice("深圳")17 print(sz.sname)18 19 #访问静态字段20 print(Provice.country)21 22 输出结果:23 深圳24 中国
方法
方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。
- 普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;
- 类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;
- 静态方法:由类调用;无默认参数;
1 #!/usr/bin/env python 2 #coding=utf-8 3 __author__ = 'yinjia' 4 5 6 class Provice: 7 #静态字段 8 country = "中国" 9 10 def __init__(self,name):11 temp = "xxx"12 #普通字段,在对象中13 self.name = name14 15 #类方法16 @classmethod17 def xing(cls):18 print("xxxxxoooo")19 20 #静态方法21 @staticmethod22 def test(arg1,arg2):23 print("abc")24 25 #普通方法,在类中26 def show(self):27 print('show')28 29 #访问类方法30 Provice.xing()31 32 #访问静态方法33 Provice.test(1,2)34 35 #访问普通方法36 obj = Provice("yin")37 obj.show()
属性
- 属性的基本使用
- 属性的定义方式
1、属性的基本使用
定义时在普通方法的基础上添加 @property 装饰器;属性仅有一个self参数; 调用时无需括号访问。
2、属性的定义方式有两种
- 装饰器 即:在类的普通方法上应用@property装饰器
- 静态字段 即:在类中定义值为property对象的静态字段
Python中的类有经典类和新式类,新式类的属性比经典类的属性丰富,如果类继object,那么该类是新式类 。
1 #!/usr/bin/env python 2 #coding=utf-8 3 __author__ = 'yinjia' 4 5 6 class Shoops: 7 8 def __init__(self,price,discount): 9 # 原价10 self.original_price = price11 # 折扣12 self.discount = discount13 14 @property15 def price(self):16 # 实际价格 = 原价 * 折扣17 new_price = self.original_price * self.discount18 return new_price19 20 21 obj = Shoops(100,0.8)22 print(obj.price) # 获取商品价格
新式类,具有三种@property装饰器,分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法;可将三个方法定义为对同一个属性:获取、修改、删除。
1 #!/usr/bin/env python 2 #coding=utf-8 3 __author__ = 'yinjia' 4 5 6 class Shoops(object): 7 8 def __init__(self,price,discount): 9 # 原价10 self.original_price = price11 # 折扣12 self.discount = discount13 14 @property15 def price(self):16 # 实际价格 = 原价 * 折扣17 new_price = self.original_price * self.discount18 return new_price19 20 @price.setter21 def price(self, value):22 self.original_price = value23 24 @price.deleter25 def price(self):26 del self.original_price27 28 obj = Shoops(100,0.8)29 print(obj.price) # 获取商品价格30 obj.price = 200 # 修改商品原价31 print(obj.price)32 del obj.price # 删除商品原价
静态字段定义值为property对象,当使用静态字段的方式创建属性时,经典类和新式类无区别。
property的构造方法中有个四个参数,分别如下:
- 第一个参数是方法名,调用
对象.属性
时自动触发执行方法 - 第二个参数是方法名,调用
对象.属性 = XXX
时自动触发执行方法 - 第三个参数是方法名,调用
del 对象.属性
时自动触发执行方法 - 第四个参数是字符串,调用
对象.属性.__doc__
,此参数是该属性的描述信息
1 #!/usr/bin/env python 2 #coding=utf-8 3 __author__ = 'yinjia' 4 5 6 class Shoops(object): 7 8 def __init__(self,price,discount): 9 # 原价10 self.original_price = price11 # 折扣12 self.discount = discount13 14 def get_price(self):15 # 实际价格 = 原价 * 折扣16 new_price = self.original_price * self.discount17 return new_price18 19 def set_price(self, value):20 self.original_price = value21 22 def del_price(self):23 del self.original_price24 25 PRICE = property(get_price, set_price, del_price, '价格属性描述...')26 27 obj = Shoops(100,0.8)28 print(obj.PRICE) # 自动调用第一个参数get_price方法获取商品价格29 obj.PRICE = 200 # 自动调用第二参数set_price方法修改商品价格30 print(obj.PRICE)31 del obj.PRICE # 自动调用第三个参数del_price删除商品价格32 print(obj.PRICE.__doc__) #自动获取第四个参数设置的值
类成员修饰符
类成员有两种形式:
- 私有成员 即:在任何地方都能访问
- 公有成员 即:只有在类的内部才能方法
静态字段
1 class Shop: 2 3 name = "公有静态字段" 4 5 def func(self): 6 print Shop.name 7 8 class test(Shop): 9 10 def show(self):11 print C.name12 13 14 Shop.name # 类访问15 16 obj = Shop()17 obj.func() # 类内部可以访问18 19 obj_son = test()20 obj_son.show() # 派生类中可以访问
1 class Shop: 2 3 __name = "私有静态字段" 4 5 def func(self): 6 print Shop.__name 7 8 class test(Shop): 9 10 def show(self):11 print C.__name12 13 14 Shop.__name #错误! 类不能访问15 16 obj = Shop()17 obj.func() # 正确!类内部可以访问18 19 obj_son = test()20 obj_son.show() #错误! 派生类中不能访问
普通字段
1 class C: 2 3 def __init__(self): 4 self.foo = "公有字段" 5 6 def func(self): 7 print self.foo # 类内部访问 8 9 class D(C):10 11 def show(self):12 print self.foo # 派生类中访问13 14 obj = C()15 16 obj.foo # 通过对象访问17 obj.func() # 类内部访问18 19 obj_son = D();20 obj_son.show() # 派生类中访问
1 class C: 2 3 def __init__(self): 4 self.__foo = "私有字段" 5 6 def func(self): 7 print self.foo # 类内部访问 8 9 class D(C):10 11 def show(self):12 print self.foo # 派生类中访问13 14 obj = C()15 16 obj.__foo # 错误!通过对象访问 17 obj.func() # 正确!类内部访问 18 19 obj_son = D();20 obj_son.show() # 错误!派生类中访问
带有下划线的方法
1 class Foo(): 2 3 #公有静态字段 4 xo = "xo" 5 #私有静态字段,带下划线表示私有成员,只能供内部访问 6 __ox = "ooxxx" 7 8 def __init__(self): 9 #私有普通字段10 self.__name = "私有字段"11 #公有普通字段12 self.__psd = 12313 14 #带有下划线方法15 def __dele(self):16 print("abc")17 18 def te(self):19 self.__dele() 20 21 22 obj1 = Foo()23 obj1.te() #只能通过另一个关联方法去访问
类的特殊成员
1. __module__ 和 __class__
__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类是什么
1 #!/usr/bin/env python2 # -*- coding:utf-8 -*-3 __author__ = 'yinjia'4 5 class C:6 7 def __init__(self):8 self.name = 'yinjia'
1 #!/usr/bin/env python2 #coding=utf-83 __author__ = 'yinjia'4 5 from lib.a import C6 7 obj = C()8 print obj.__module__ # 输出 lib.a,即:输出模块9 print obj.__class__ # 输出 lib.a.C,即:输出类
2、__call__
__call__ 方法的执行是由对象后加括号触发的
1 #!/usr/bin/env python 2 #coding=utf-8 3 __author__ = 'yinjia' 4 5 6 class Foo: 7 """ 8 我是模块 9 """10 abc = 12311 12 def __init__(self):13 self.name = 'yinjia'14 15 def __call__(self, *args, **kwargs):16 print("call")17 18 19 r = Foo() #执行__init__方法20 21 r() #执行__call__方法
3、__getitem__、__setitem__、__delitem__
用于索引操作,如字典。以上分别表示获取、设置、删除数据
1 #!/usr/bin/env python 2 #coding=utf-8 3 __author__ = 'yinjia' 4 5 6 class Foo: 7 """ 8 我是模块 9 """10 abc = 12311 12 def __init__(self):13 self.name = 'yinjia'14 15 def __getitem__(self, item):16 print(item)17 def __setitem__(self, key, value):18 print(key,value)19 def __delitem__(self, key):20 print(key)21 22 r = Foo()23 24 r['kafad'] #执行__getitem__方法25 r['test'] = 123 #执行__setitem__方法26 del r ['aabbccdd'] #执行__delitem__方法27 r[1:3] #执行__getslice__/__getitem__28 r[1:3] = [11,22,33] #执行__setslice__/__setitem__29 del r[1:3] #__delslice__/__delitem__
4. __iter__
用于迭代器,之所以列表、字典、元组可以进行for循环
1 #!/usr/bin/env python 2 #coding=utf-8 3 __author__ = 'yinjia' 4 5 6 class Foo(object): 7 8 def __init__(self, sq): 9 self.sq = sq10 11 def __iter__(self):12 return iter(self.sq)13 14 obj = Foo([11,22,33,44])15 16 for i in obj:17 print(i)
5. __dict__
输出类或对象的所有成员
1 #!/usr/bin/env python 2 #coding=utf-8 3 __author__ = 'yinjia' 4 5 6 class Foo: 7 """ 8 我是模块 9 """10 abc = 12311 12 def __init__(self):13 self.name = 'yinjia'14 15 def __call__(self, *args, **kwargs):16 print("call")17 return 118 def __getitem__(self, item):19 print(item)20 def __setitem__(self, key, value):21 print(key,value)22 def __delitem__(self, key):23 print(key)24 25 r = Foo()26 print(r.__dict__) #输出对象所有的字段属性27 print(Foo.__dict__) #输出类所有的方法
执行基类构造方法
1 class Annimal: 2 def __init__(self): 3 print("父类构造方法") 4 self.ty = "动物" 5 def eat(self): 6 print("%s%s在吃东西" % (self.name,self.n)) 7 8 class Cat(Annimal): 9 def __init__(self,name):10 print("子类构造方法")11 self.name = name12 self.n = "猫"13 super(Cat,self).__init__() #常用第一种方法,执行父类初始化数据14 #Annimal.__init__(self) #第二种方法15 16 #数据初始化17 c = Cat("张三的")18 c.eat()19 print(c.__dict__)20 21 输出结果:22 子类构造方法23 父类构造方法24 张三的猫在吃东西25 { 'name': '张三的', 'n': '猫', 'ty': '动物'}