魔术方法(内置方法)
类类里面内置的双下划线开头的一些地方,它们具有特殊的功能,我们称之为魔术方法,简称魔法
比如:__init__
1.__str__,__repr__方法
__str__:当打印和输出对象时,自动触发str方法,但还是str必须要有返回值,不然会报错,而且返回值必须是字符串。
__repr__:它的使用和str一样,如果一个类中有既有repr也有str,会执行str,str的优先级大于repr
class Student(): def __init__(self, name, age): self.age = age self.name = name def __str__(self): print('from str') return 'from str' def __repr__(self): print('from repr') return 'from repr' stu = Student('kevin', 28) print(stu)
我们一般用__str__方法
2.__del__方法
当程序结束时,会触发del方法
当删除对象时,也会触发del方法
class Student(): def __init__(self, name, age): self.age = age self.name = name self.f = open("a.txt", "w", encoding="utf8") def __del__(self): print('from del') self.f.close() stu = Student('kevin', 12) res = stu.f print(stu.name) del stu
__del__可以做一些垃圾清理,关闭文件等
3.isinstance(obj,cls)和issubclass(sub,super)
isinstance(obj,cls)判断对象是不是该类产生的
issubclass(sub,super)判断该类有没有继承父类
class Animal(): pass class People(Animal): pass stu = People() print(isinstance(stu, People)) print(issubclass(People, Animal))
4.__doc__(documen)方法
查看类的详细信息,也就是类的注释,此方法不能继承父类
class Foo(): '''这是foo的注释''' def func(self): '''func''' pass class So(Foo): '''这是so的注释''' pass print(Foo.__doc__)#''这是foo的注释''' print(So.__doc__) #'''这是so的注释'''
5.__enter__和__exit__方法
__enter__:当出现with语句时就会执行类中的该方法,有返回值则赋给as后面的变量名
__exit_:当with中的代码块完成就会触发exit方法,如果__exit()返回值为True,那么异常会被清空,就好像啥都没发生一样,with后的语句正常执行
class With(): def __init__(self): pass def __enter__(self): print('打开文件') def __exit__(self, exc_type, exc_val, exc_tb): print('该我表演了') stu = With() with With() as f: print('with代码块')
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 with Open('a.txt') as f: print('=====>执行代码块') raise AttributeError('***着火啦,救火啊***')# 抛出异常信息
print('0'*100) #------------------------------->不会执行
exit中的三个形参
exc_type:异常的类型
exc_val:异常值
exc_tb:追溯信息
__exit__()中的三个参数分别代表异常类型,异常值和追溯信息,with语句中代码块出现异常,则with后的代码都无法执行
面试题:说说你对with上下文管理的理解
6.__setattr__,__delattr__,__getattr__方法
——setattr——:你使用点语法,设置一个不存在的属性值就会自动触发__setattr__
__delattr__:删除属性时候触发
__getattr__:只有在使用点调用属性且属性不存在的时候才会触发
class Foo: x=1 def __init__(self,y): self.y=y def __getattr__(self, item): print('----> from getattr:你找的属性不存在') def __setattr__(self, key, value): print('----> from setattr') # self.key=value #这就无限递归了,你好好想想 # self.__dict__[key]=value #应该使用它 def __delattr__(self, item): print('----> from delattr') # del self.item #无限递归了 self.__dict__.pop(item) #__setattr__添加/修改属性会触发它的执行 f1=Foo(10) print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值 f1.z=3 print(f1.__dict__) #__delattr__删除属性的时候会触发 f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作 del f1.a print(f1.__dict__) #__getattr__只有在使用点调用属性且属性不存在的时候才会触发 f1.xxxxxx
7.__setitem__,__getitem,__delitem__方法
class Foo: def __init__(self,name): self.name=name def __getitem__(self, item): print(self.__dict__[item]) def __setitem__(self, key, value): self.__dict__[key]=value def __delitem__(self, key): print('del obj[key]时,我执行') self.__dict__.pop(key) def __delattr__(self, item): print('del obj.key时,我执行') self.__dict__.pop(item) f1=Foo('sb') f1['age']=18 f1['age1']=19 del f1.age1 del f1['age'] f1['name']='alex' print(f1.__dict__)
8.__call__方法
对象后面括号就会触发该方法
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
class Foo: def __init__(self): pass def __call__(self, *args, **kwargs): print('__call__') obj = Foo() # 执行 __init__ obj() # 执行 __call__
反射
在Python中,反射指的是通过字符串来操作对象的属性,涉及到四个内置函数的使用(Python中一切皆对象,类和对象都可以用下述四个方法)
hasattr(object,‘name’),判断对象有没有name属性
getattr(object,‘name’,deffauit=None):等同于对象.属性名,该属性不存在就返回None
setattr(object,‘age’,v):等同于对象.属性名=值
delattr(object,‘age’):等同于del 对象.属性
class Teacher: def __init__(self,full_name): self.full_name =full_name t=Teacher('Egon Lin') # hasattr(object,'name') hasattr(t,'full_name') # 按字符串'full_name'判断有无属性t.full_name # getattr(object, 'name', default=None) getattr(t,'full_name',None) # 等同于t.full_name,不存在该属性则返回默认值None # setattr(x, 'y', v) setattr(t,'age',18) # 等同于t.age=18 # delattr(x, 'y') delattr(t,'age') # 等同于del t.age
反射案列
class FtpServer: def serve_forever(self): while True: inp = input('input your cmd>>: ').strip() # get a.txt put a.txt cmd, file = inp.split() # get a.txt ['get', 'a.txt'] # hasattr(self, 'get') # hasattr(self, 'put') if hasattr(self, cmd): # 根据用户输入的cmd,判断对象self有无对应的方法属性 # getattr(self, ’get‘) get或者put的内存地址 func = getattr(self, cmd) # 根据字符串cmd,获取对象self对应的方法属性 func(file) def get(self, file): print('Downloading %s...' % file) def put(self, file): print('Uploading %s...' % file) server = FtpServer() server.serve_forever()
异常剩余内容
1. 异常就是错误发生的信息,我们必须要做处理,否则,后续代码无法正常运行
2. 如何捕捉异常
try: 被检测的代码 except 异常类型: pass else: print() finally: print()
3. 我们自己如何抛出异常:raise
class Animal(): # @abc.abstractmethod def speak(self): raise Exception("请先实现speak方法") class People(Animal): def speak(self): pass # pass """主动抛出异常""" stu = People() stu.speak()
4. 自定义异常
class MyException(BaseException): def __init__(self, msg): self.msg = msg def __str__(self): return self.msg raise MyException("这是异常信息")
补充
以字符串形式导入模块
import time time.sleep(3) res = getattr(time, 'sleep') # built-in print(res) res(3) # time.sleep(3) getattr(time, 'sleep')(3) import time time = __import__("time") # 以字符串的形式导入模块 time.sleep(3) random = __import__("random") res = random.randint(0, 9) print(res)
标签:__,反射,内置,name,python,self,.__,print,def From: https://www.cnblogs.com/shanghaipudong/p/17511929.html