目录
组合
它不是一个新的技术栈,它是对象的另外一种用法
什么是组合?
组合就是,一个对象拥有一个属性,该属性的值是另外一个对象
class Foo(): def __init__(self,m): self.m = m class Bar(): def __init__(self,n) self.n = n """一个对象拥有一个属性,该属性的值是另外一个对象""" obj = Bar(10) obj1 = Foo(20) # 超级对象,通过一个属性可以访问到另一个对象的值 obj.x = obj1 print(obj.x.m)
什么情况下使用继承?什么情况下使用组合?
继承一般情况用在:什么是什么的情况 is
组合一般用在:什么有什么的情况 has
反射
在python中,反射指的是通过字符串来操作对象的属性,涉及到四个内置函数的使用(python中一切皆对象,类和对象都可以用下述四个方法)
四个内置函数:
getattr:获取属性 # 用的最多
setattr:设置属性
hasattr:判断是否有某个属性
delattr:删除
class Student(): school = 'SH' def __init__(self,name,age): sel.name = name self.age = age def func(self): print('from func') def index(self): print('from index') stu = Student('kevin',20) # attr = input('请输入你要操作的属性名:') # print(stu.school) # print(stu."school") """反射:就是通过字符串的形式来操作对象的属性""" # 1.获取属性 """当你查询的属性不存在的时候,如果给了第三个参数,就返回第三个参数""" # res = getattr(stu,'school1',666) """如果你给了第三个参数,查询的属性也存在,那就直接返回属性对应的值,默认值就没用了""" # res=getattr(stu,'school',666) # res1=getattr(stu,'name') # res1=getattr(stu,'name') # print(res,res1,res2) # print(res) # 函数的用法 """必须掌握""" res=getattr(stu,'func1',stu.index) # 用的是最多的 print(res) res() # setattr设置 # setattr(stu,'x',666) # stu.x = 666 # print(stu.__dict__) # hasattr print(hasattr(stu,'func')) if hasattr(stu,'func') getattr(stu,'func')() else: pass # delattr # delattr(stu,'name') # del stu.name # print(stu.__dict) # import time # time=__import__('time') # import time # print(time.time()) random = __import__('random') print(random.randint(0,8))
内置方法之魔术方式(重要)
它的特点就是双下划线的方法,他满足一定的条件就会自动触发,简称魔法
面向对象中有哪些魔术方法?怎么使用?
只学10个魔术方法,不止有10个魔术方法
1. __init__
2. __str__,__repr__
class Student(): def __init__(self,name,age): self.name = name self.age = age def __str__(self): # 这个用的是最多的 print('str') return 'from str' def __repr__(self): print('repr') return 'from repr' stu = Student('ly',20) # print(stu) # print('repr:',repr(stu)) print('str:',stu(stu)) ''' 1. 打印对象的时候,输出对象的时候会自动触发类中得__str__方法 2. 返回值必须是字符串形式 3. 如果它跟__repr__方法同时存在,__str__的优先级更高 '''
3. __del__
class Mysql(): def __init__(self,ip,port): self.ip = ip self.port = port self.f = open('a.txt','w') def __del__(self): print('from _del') self.f.close() mysql = MySQL('127.0.0.1',3306) print('12') print(isinstance(123,str)) print(type(12) is int) class Foo(): pass class Bar(foo): pass class Bar1(): pass print(issubclass(Bar1,Foo)) class Foo(): ''' 我是描述信息 我是描述信息 我是描述信息 ''' pass class Bar(foo): pass print(Bar.__doc__)
4. __enter__和__exit__
class open(): def __init__(self,name): self.name = name def __enter__(self): print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量') # return self def __exit__(self,exc_type,exc_val,exc_tb): print('with中代码块执行完毕是执行我啊') """with它可以用在很多地方,但是,出现with语句后面的对象中的类必须要声明__enter__和__exit__""" with open('a.txt') as f: print('执行代码块') # print(f,f.name) class Open(): def __init__(self,name): self.name = name def __enter__(self): print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量') def __exit__(self,exc_type,exc_val,exc_tb): print('with 中代码块执行完毕时执行我啊') print(exc_type) # 异常类型 print(exc_val) # 异常值 print(exc_tb) # 追溯信息 return True # 如果在这个方法里面返回了True,with代码块中出现了异常,就相当于没有出现异常 """with它可以用在很多地方,但是,出现with语句后面的对象中的类必须要声明__enter__和__exit__ """如果with代码块中出现了异常,则with语句之后的代码都不能正常执行""" with Open('a.txt') as f: print('执行代码块') raise Attribute('***着火了,救火啊***') # 抛出异常,主动报错 print('0'*100) # 不会执行
5. __setattr__,__delattr__,__getattr__
class Foo(): x = 1 def __init__(self,y): self.y = y """当你找的属性不存在时,会触发__getattr__,但是必须是点语法的时候才会""" def __getattr__(self,item): print('from getattr:你找的属性不存在') def __setattr__(self,key,value): print('from setattr') # self.key = value # self.a=20 # self.key = value # 这就无限递归了,你好好想想 self.__dict__pop(item) obj=Foo(10) # obj.z obj.a=20 print(obj.a) del obj.a
6. __setitem__,__getitem__,__delitem__
class Foo(): def __init__(self,name): self.name = name """当你通过中括号获取对象的属性的时候,会自动触发__getitem__""" def __getitem__(self,item): print('__getitem__') print(self.__dict__[item]) def __setitem__(self,key,value): # key:age # value:18 print('__setitem__') self.__dict__[key] = value # self.__dict__['age'] = 18 def __delitem__(self,key): print('del obj[key]时,我执行') self.__dict__.pop(key) pass # def __delattr__(self,item): # print('del obj.key时,我执行') # self.__dict__.pop(item) obj=Foo('tom') # print(obj.name) # obj['name'] obj['age'] = 18 # obj.age = 18 print(obj.age) del obj['age']
7. call
class Foo(): def __init__(self): pass # 当对象加括号的时候会触发__call__的执行 def __call__(self,*args,**kwargs): print('__call__') obj = Foo() print(obj) obj()