面向对象
-
类
# 类定义 class ClassName: <statement -1> . . . <statement-N>
-
方法
- 正常方法:
def f():
- 匿名方法 :
# 定义一个没有名字的方法,这个方法内自己包含了输入以及输出 chu = lambda x, y: x/y chu(5, 3)
- 正常方法:
-
魔术方法:所有都以双下划线作为名字的开头和结尾,不需要人为调用,会在特定时刻自动触发
- 构造函数__init__():主要作为参数传递
class MyClass: def __init__(self, ha, he): # self代表类的实例,代表当前对象的地址,但self不是关键字,可以随意更换,但类方法必须包含参数self,且为第一个参数 print('当然也可以写其他东西,但如果需要传递参数必须写在这里') self.a = ha self.e = he def f(self): print(self.e, self.a) x = MyClass(1, 2) print(x.a, x.e) x.f()
- __new__():最先被调用的,返回类的一个实例,一般不使用
- __call__():当对象被当做函数时被调用
- __str__():当对象被当做字符串时被调用
- __repr__():和__str__()类似,但print()调用的是__str__(),而如果直接把对象当做字符串时调用的是__repr__()
- __getattr__():当访问不存在的属性时被调用
- __setattr__(self, name, value):当对成员属性设置是被调用,但有三个参数
- self获取当前对象
- name属性名称,为字符串形式
- value属性值
- 注意:在该方法中不可直接对属性进行赋值,推荐使用
super().__setattr__(name, value)
通过父类进行赋值,避免死循环
- __add__():当对象被进行加运算时被调用
- __del__():当对象被删除时被调用
-
继承
- 单继承
class FatherClass(): def __init__(self, hu): self. h = hu def speak(self): for i in range(1, self.h): print(i) class SonClass(FatherClass): # class 子类(父类) def __init__(self, hu): FatherClass.__init__(self, hu) son = SonClass(3, 7) son.speak()
- 多继承
class FatherClass0(): def __init__(self, zu, hu): self.h = hu self.z = zu def speak(self): for i in range(self.z, self.h): print(i) class FatherClass2(): def __init__(self, du, xu): self.d = du self.x = xu def walk(self): dx = {} for i in range(0,len(self.d)): dx.update({self.d[i]: self.x[i]}) return dx class SonClass(FatherClass0, FatherClass2): def __init__(self, zu, hu, du, xu): FatherClass0.__init__(self, zu, hu) FatherClass2.__init__(self, du, xu) a = 2 b = 7 c = ['k', 'h', 'dsa', 'sda'] d = [1, 2, 3, 4] sc = SonClass(a, b, c, d) sc.speak() print(sc.walk())
- super():代表父类。
class FatherClass(): def speak(self, f): print(f) class SonClass(FatherClass): def speak(self, f): super().speak(f) sc = SonClass() sc.speak(5)
- 重写
class FatherClass: def __init__(self, hu): self.h = hu def speak(self): for i in range(1, self.h): print(i) class SonClass(FatherClass): def __init__(self, hu, zu): FatherClass.__init__(self, hu) self.z = zu def speak(self): for i in range(self.z,self.h): print(i) son = SonClass(9, 4) son.speak() super(SonClass, son).speak()
-
封装:
- 私有:两个下划线开头,声明该属性或该方法为私有,只能被在类的内部调用,但也可以在外部调用
- 受保护:一个下划线开头,声明该属性或该方法为保护,可以在类和子类中被调用,但也可以在外部调用
class Person: a = 45 _b = 56 __c = 67 A = Person() print(A.a) print(A._b) # 外部调用受保护属性 print(A._Person__c) # 外部调用私有属性
-
多态:
class A: def __init__(self, a): self.a = a def zimu(self): print(self.a) class B: def __init__(self, b): self.b = b def zimu(self): print(self.b) a = A(1) a.zimu() b = B(2) b.zimu()
-
抽象:python3中并没有抽象类以及接口的概念,如果需要实现,可以借用abc模块
import abc class Abstract(metaclass=abc.ABCMeta): @abc.abstractmethod # 定义抽象方法 def f(self): pass @abc.abstractstaticmethod # 定义静态抽象方法 def sf(): pass @abc.abstractclassmethod # 定义类抽象方法 def cf(): pass # 抽象类也可以创建非抽象方法 def sleep(self): print('hahahahaha') # 实现抽象类必须复写所有抽象方法 class af(Abstract): def f(self): print('f') def sf(self): print('sf') def cf(self): print('cf') af = af() af.f() af.sf() af.cf()
-
语法糖:也可以叫做修饰器或者装饰器,以@开头,在不改变源代码的基础上添加新需求
def f(func): print('*'*20) func() print('+'*20) @f def p(): print('p') p
等同于
def f(func): print('*'*20) func() print('+'*20) def p(): print('p') f(p)
-
主函数:
if __name__ == "__main__"
def f(): print("f") def p(): print("p") if __name__ == "__main__": f()