复习
class 类名(父类,父类2):
静态属性 = '' #静态属性 类属性
def __init__(self): #初始化方法
self.name = 'alex'
def func(self):
print(self,age) #动态属性 方法
对象 = 类名()
对象.方法名()
对象.属性名
对象.name
对象.age = 18
对象.func()
组合:表达的是什么有什么 *****
一个类的属性是另外一个类的对象
命名空间:类和对象分别存在不同的命名空间中
面向对象的三大特性:继承、多态、封装
继承:单继承 :****
父类(超类、基类)
子类(派生类):派生方法和派生属性,
子类的对象在调用方法和属性:先用自己的,自己没有才用父类的
多继承:***(面试)
不会超过三个父类,不要超过三层 ***
如果子类自己有用自己的,如果没有就用离子类最近的那个父类的方法
抽象类和接口类**
经典类和新式类:继承规则不同,深度优先和广度优先 *****(面试)
super 只能在python3中使用 ****
super是根据mro广度优先顺序找上一个类
多态 ***:(面试)
多态和鸭子类
封装:(面试)
私有的 __名字
只能在类的内部调用,子类都无法继承
三个装饰器
@property ****
@staticmethod ***
@classmethod *****当一个方法只使用了类的静态变量时,就给这个方法加上@classmethod装饰器,默认传cls参数
'''
class Teacher: pass class Course: def __init__(self,name,price,period): self.name = name self.price = price self.period = period python = Course('python',19800,'6 months') class Classes: def __init__(self,name,course,teacher,school): self.name = name self.course = course self.teacher = teacher self.school = school pys9 = Classes('pytho_s9',python,'tim','oldboy') print(pys9.course.name) python.name = 'python全栈' print(pys9.course.name)
# isinstance和issubclass
# isinstance(obj,cls)检查是否obj是否是类 cls 的对象
# class A:
# pass
# a = A()
# print(isinstance(a,A))
# issubclass(sub, super)检查sub类是否是 super 类的派生类
# class A:
# pass
# class B(A):pass
# a = A()
# print(issubclass(B,A))
# 反射:是用字符串类型的名字去操作变量
# 反射就没有安全问题
# 反射对象中的属性和方法 hasattr getattr setattr delatter
# class A:
# def func(self):
# print('in func')
# a = A()
# a.name = 'alex'
# a.age = 64
# 反射对象的属性
# ret = getattr(a,'name') #通过变量名的字符串形式取到的值
# get = input('>>>>>>')
# print(getattr(a,get))
# print(a.__dict__[get])
# 反射对象里的方法
# ret = getattr(a,'func')
# ret()
class A: price = 20 def func(self): print('in func') # 反射类的属性 print(getattr(A,'price'))
# 反射类的方法:classmethod staticmethod # 类名.方法名 class A: price = 20 @classmethod def func(cls): print('in func') print(getattr(A,'func')) ret = getattr(A,'func') ret()
# 模块 # 反射模块的属性 import my # print(my.day) print(getattr(my,'day')) # 反射模块的方法 ret = getattr(my,'wahaha') ret()
# 反射自己的模块中的变量 # year = 2019 # import sys # print(sys.modules['__main__']) # def qqxing(): # print('qqxing') # print(getattr(sys.modules['__main__'],'year')) # 反射自己模块中的方法或函数 # print(getattr(sys.modules['__main__'],'qqxing')) # ret = getattr(sys.modules['__main__'],'qqxing') # ret() # # get = input('>>>>>>> ') # print(getattr(sys.modules['__main__'],get)) # print(getattr(sys.modules[__name__],get)) # 一个模块中的类能不能反射的到 # import my # print(getattr(my,'C')()) # if hasattr(my,'name'): # getattr(my,'name')
# setattr() 设置修改变量 class A: pass a = A() setattr(A,'name','tim') setattr(a,'name','gim') print(A.name) print(a.name)
# delattr()删除一个变量
delattr(a,'name')
print(a.name)
# obj.__str__ # 内置的类方法和内置的函数之间有着千丝万缕的联系 class Teacher: def __init__(self,name,salary): self.name = name self.salary = salary def __str__(self): return "Teacher's object : %s"%self.name # a = A() nezha = Teacher('哪吒',250) print(nezha) # print(a) #打印一个对象的时候,就是调用a.__str__ # object 有个双下str,一旦被调用,就返回调用这个方法的内存地址 # print('%s:%s'%('A',a)) #%s str() 直接打印 实际上都是走__str__
Teacher's object : 哪吒
# %s str() 直接打印 实际都是走__str__
# %r repr() 直接打印 实际都是走__repr__ repr是str的备胎,反过来不行
# obj.__repr__ class Teacher: def __init__(self,name,salary): self.name = name self.salary = salary def __str__(self): return "Teacher's object : %s"%self.name def __repr__(self): return str(self.__dict__) # a = A() nezha = Teacher('哪吒',250) print(nezha) print(repr(nezha)) print('>>>>>%r'%nezha)
# %s str() 直接打印 实际都是走__str__
# %r repr() 直接打印 实际都是走__repr__ repr是str的备胎,反过来不行(str不能做repr的备胎)
#str(obj)的时候,实际上是内部调用了obj.__str__方法,如果str方法有返回值,那么他返回的必定是一个字符串
#如果没有__str__方法,会先找本类中的__repr__方法,在没有再找父类中的__str__
# __del__ class A: def __del__(self): print('执行我拉') a = A() del a #del 既执行了这个方法,又删除了变量, print(a)
# __call__ class A: def __init__(self,name): pass def __call__(self): print('执行我了') a = A('tim') a() #相当于执行了__call__方法