类成员
类成员分为三大类:字段、方法、属性
注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段。而其他的成员,则都是保存在类中,即:无论对象的多少,在内存中只创建一份。
字段
- 普通字段:属于对象
- 静态字段:属于类
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 = name 14 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 = name 14 15 #类方法 16 @classmethod 17 def xing(cls): 18 print("xxxxxoooo") 19 20 #静态方法 21 @staticmethod 22 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 = price 11 # 折扣 12 self.discount = discount 13 14 @property 15 def price(self): 16 # 实际价格 = 原价 * 折扣 17 new_price = self.original_price * self.discount 18 return new_price 19 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 = price 11 # 折扣 12 self.discount = discount 13 14 @property 15 def price(self): 16 # 实际价格 = 原价 * 折扣 17 new_price = self.original_price * self.discount 18 return new_price 19 20 @price.setter 21 def price(self, value): 22 self.original_price = value 23 24 @price.deleter 25 def price(self): 26 del self.original_price 27 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 = price 11 # 折扣 12 self.discount = discount 13 14 def get_price(self): 15 # 实际价格 = 原价 * 折扣 16 new_price = self.original_price * self.discount 17 return new_price 18 19 def set_price(self, value): 20 self.original_price = value 21 22 def del_price(self): 23 del self.original_price 24 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.name 12 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.__name 12 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 = 123 13 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 python 2 # -*- coding:utf-8 -*- 3 __author__ = 'yinjia' 4 5 class C: 6 7 def __init__(self): 8 self.name = 'yinjia'
1 #!/usr/bin/env python 2 #coding=utf-8 3 __author__ = 'yinjia' 4 5 from lib.a import C 6 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 = 123 11 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 = 123 11 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 = sq 10 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 = 123 11 12 def __init__(self): 13 self.name = 'yinjia' 14 15 def __call__(self, *args, **kwargs): 16 print("call") 17 return 1 18 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 = name 12 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': '动物'}