类(面向对象编程)
一、类的适用场景
1 将多个具有类似功能的函数用一个统一的接口调用
2 想要为多个函数,封装一些相同的值
二、类的基础结构
1 封装
1 class Foo: 2 country = "china" 3 def __init__(self, name, age) 4 self.name = name 5 self.age = age 6 def manner_1(self): 7 print("operating...")
2 封装成员的解释
1 #类对象 2 Foo 3 4 #静态字段,保存在类中,通过类或实例对象访问 5 country 6 7 #普通字段,保存在实例对象中, 只能通过实例对象访问 8 self.name 9 self.age 10 11 #初始化(结构化)方法,在生成实例化对象时,自动执行 12 __init__ 13 14 #普通方法,保存在类中,第一个参数需为self,self表示传入的实例对象,需通过实例对象来调用类中的方法 15 manner_1
3 调用
1 #生成一个实列对象,并执行类中的__init__()方法 2 obj = Foo("xiaokai", "18") 3 4 #通过对象调用类中的普通方法 5 obj.manner_!() 6 7 #通过类调用静态字段 8 Foo.country 9 10 #通过实例对象调用静态和普通字段 11 obj.country 12 obj.name
注意:类中的方法需要经过,实例化后才可调用
三、类的继承
1.完全继承
1 class Father: 2 def F_manner_1() 3 print("F1") 4 5 class Son(Father): 6 def S_manner_!(): 7 print("S1") 8 9 obj = Son() 10 obj.S_manner_1() 11 obj.F_manner_1()
2.部分继承
1 class Father: 2 def F_manner_1() 3 print("F1") 4 def F_manner_1() 5 print("F2") 6 7 class Son(Father): 8 def F_manner_!(): 9 print("S1") 10 11 obj = Son() 12 obj.F_manner_1()
3.修改继承(为继承方法增加新功能)
1 class Father: 2 def F_manner_1() 3 print("F1") 4 def F_manner_2() 5 print("F2") 6 7 class Son(Father): 8 def S_manner_1(): 9 print("S1") 10 supper(Son, self).F_manner_1 #Father.F_manner_1(self) 11 12 obj = Son() 13 obj.F_manner_1()
4.类的多继承
4.1 继承顺序:从左到右,由浅到深
四、字段的修改
1 class Foo: 2 country = "China" 3 def __init__(self, name, age): 4 self.name = name 5 self.age = age 6 7 #修改静态字段 8 Foo.country = "Russia" 9 #增加静态字段 10 Foo.language = "Russian" 11 12 obj = Foo("xiaokai", "21") 13 #修改普通字段 14 obj.name = "xiaohong" 15 #增加普通字段 16 obj.hobby = "learning"
注意:也可通过实例对象修改静态字段,但该修改只保存在实例对象中
五、面向对象的第三大特性(多态)
1 in python 不需要关注,因为python原生多态(只用规定参数名,不用规定参数类型)
2 在其他语言中,传入的参数需要规定类型。但如果的传入的参数类型是某个类的话,该参数还可接收该类的子类
六、类成员
(一) 字段
1 普通字段:封装在对象中,只能通过实例对象访问
2 静态字段:封装在类中,类和实例对象都能访问
(二) 方法
1 普通方法:封装在类中,由实例对象调用
2 静态方法:封装在类中,由类调用
1 @staticmethod 2 def manner_!(): 3 pass
3 类方法:封装在类中,由类调用
1 @classmethod 2 def manner_!(cls): 3 pass
4 静态方法和类方法的区别
静态方法没有默认的参数,类方法有默认的参数(cls),但类方法在通过类调用时会自动传入该参数(类对象)
(三) 属性or特性
1 构造形式一
1 @property 2 def per(self): 3 print("operating...") 4 return result 5 6 @per.setter 7 def per(self, valur): 8 print("uploading...") 9 10 @per.deleter 11 def per(self): 12 print("delete...") 13 14 obj = 类() 15 ret = obj.per #调用上边的第一个方法 16 obj.per = value #调用上边的第二个方法 17 del obj.per #调用上边的第三个方法
2 构造形式二
1 class Foo: 2 def f1(self): 3 print("operating...") 4 return result 5 6 def f2(self, v): 7 print("set value...") 8 9 def f3(self): 10 print("delete...") 11 12 per = property(fget=f1, fset=f2, fdel= f3)
七、成员修饰符
1 私有成员:在字段名or方法名前加两下划线(_),使之只能被类内部调用(字类内部也无法调用),不允许外部访问
2 共有成员:除上述特殊命名外的字段和方法,可被内部调用,也可被外部访问
八、特殊成员(在命名前后带双下划线的成员)
1 #类(),自动执行自己写的类中的该方法 2 __init__() 3 #类(),自动执行type原始类中的该方法 4 __call__() 5 #int()函数会调用对象的__int__方法,获得返回值并输出 6 __int__() 7 #同上 8 __str__() 9 #对象+对象时,自动调用第一个对象的该方法 10 __add__() 11 #对象被销毁时自动触发 12 __del__() 13 #将对象中的成员以字典返回 14 __dict__ 15 16 #对象[index]时,自动调用 17 __getitem__() 18 #对象[index] = value时,自动调用 19 __setitem__() 20 #del 对象[index]时,自动调用 21 __delitem__() 22 #注意切片时,也是调用上述的三个方法,不过传入的是slice对象 23 24 #内部有iter方法的都是可迭代对象,该方法的返回值为一个迭代器 25 __iter__()
九、所有的类都是type()的对象
1 #下面两段代码是相等的 2 class Foo(object): 3 name = "xiaokai" 4 5 #第一个参数填写类名,第二个参数为继承类,第三个参数为类成员 6 Foo = type("Foo", (object,), {"name": "xiaokai"})
十、通过自定义原始类创建类对象
1 源码展示
1 #自定义的原始类 2 class MyType(type): 3 def __init__(self, what, bases=None, dict=None) 4 super(MyType, self).__init__(what, bases, dict) 5 def __call__(self, *args, **kwargs): 6 obj = self.__new__(self, *args, **kwargs) 7 self.__init__(obj) 8 9 class Foo(object): 10 #指定用自定义的原始类来创建类对象 11 __metaclass__ = MyType 12 def __init__(self, name): 13 self.name = name 14 def __new__(cls, *args, **kwargs): 15 return object.__new__(cls, *args, **kwargs) 16 17 #第一阶段:解释器从上到下执行代码,创建Foo类对象 18 19 #第二阶段:通过Foo类对象,创建obj实例对象 20 obj = Foo()
2 图表示例
十一、反射
1 #通过str的形式,帮我们去对象中取成员 2 getattr(对象,成员名) 3 4 #通过str的形式,帮我们判断对象中是否有该成员 5 hasattr(对象,成员名) 6 7 #通过str的形式,帮我们在对象中添加成员 8 setattr(对象,变量名,值) 9 10 #通过str的形式,帮我们在对象中删除成员 11 delattr(对象,变量名)
十二、单例模式(不创建新实例对象,一直使用一个实例对象)
1 class Foo: 2 __V = None 3 4 @classmethod 5 def get_instance(cls): 6 if cls.__V: 7 return cls.__v 8 else: 9 cls.__V = Foo() 10 return cls.__V 11 12 #不使用类() 13 obj_1 = Foo.get_instance() 14 obj_2 = Foo.get_instance()