魔术方法(内置方法)(面试题)
# 类里面内置的双下划线开头的一些方法,他们具有特殊的功能,我们称之为是魔术方法,简称魔法
比如:__init__
"""魔术方法的学习只需要掌握每个方法什么时候触发或者执行"""
1. __str__, __repr__方法
# __str__,__repr__方法
class Student():
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def __str__(self):
print("我执行了")
# return None
"""__str__方法返回值必须是字符串类型"""
# return "123"
return "name:%s" % self.name
# return 123
def __repr__(self):
return "name1:%s" % self.name
stu = Student("kevin", 19, 'male')
"""也就是说,__str__方法内部返回什么结果,打印的就是返回的结果,"""
# print(stu) # 当打印或者输出对象的时候,会自动触发__str__的执行
print('from repr: ',repr(stu)) # __next__ __len__
print('from str: ',str(stu))
"""__repr__:它的功能和__str__一样,只不过,只写了他们两个其中之一,都会执行,但是,如果两个都写了,__str__它的优先级高于_repr__"""
# 我们一般用的是__Str__方法
2. __del__方法
class Student():
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
self.f = open("a.txt", "w", encoding="utf8")
# 我执行了:
# 1. 当删除对象的时候,会自动触发函数的执行
# 2. 当程序结束的时候,也会自动触发执行
def __del__(self):
print("我执行了")
"""可以做一些清理垃圾的操作"""
self.f.close()
# # close() 方法用于关闭一个已打开的文件
# 关闭后的文件不能再进行读写操作,否则会触发 ValueError 错误。
# close() 方法允许调用多次。
stu = Student("kevin", 19, 'male')
# del stu
print("123")
3. isinstance(obj,cls)和issubclass(sub,super)方法
class People():
pass
class Student(People):
pass
# stu = Student()
# print(isinstance(stu, Student)) # True
# print(isinstance("hellowrold", str))
# res = 'helloworld' # <class 'str'>
# # res1 = int
#
# print(type(res))
#
# # res = str('helloworld')
print(issubclass(Student, People))
4. __doc__方法
class Foo:
"""
author:kevin
date:2023-01-01
email:liyangqit@163.com
这是注释"""
pass
class Bar(Foo):
"""这是Bar"""
pass
# document:可以查看出类内部的详细信息,其实就是注释里面的内容
# print(Foo.__doc__)
print(Bar.__doc__) # 这个特性不能够继承到父类
5. __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 Open('a.txt') as f:
print('=====>执行代码块')
print('=====>执行代码块')
print('=====>执行代码块')
print('=====>执行代码块')
print('=====>执行代码块')
print('=====>执行代码块')
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 Tr
with Open('a.txt') as f:
print('=====>执行代码块')
raise AttributeError('***着火啦,救火啊***')
print('0'*100) #------------------------------->不会执行
5. 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) #------------------------------->不会执行
面试题:探探你对with上下文管理协议的理解?
1.with可以自动打开文件和关闭文件
2.with创建上下文管理器,只要出现with语句,他就会自动的触发with后面的那个对象的类里面的enter和 exit ,那enter什么时候触发呢?那就是出现with语句的时候,会自动触发enter的函数,enter里面的返回值返回什么就会给with语句后面的as变量
3. 当触发enter语句之后,就会执行我with代码块,当with代码块执行完之后就会执行另外一个方法叫exit的方法,然后关闭文件的时候,可以在exit里面做一些关闭的操作
4.如果我们在with代码块里面出现了异常信息,那我们可以在里面可以查看到一下信息,比如:异常类型,异常值,和追溯信息等,如果在exit里面直接返回Tuer,
那在with代码块里面抛出异常的时候,相当于没有发生一样
5.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')
# print(key, value) # z 1
# self.z = 1
# 你使用点语法,设置一个不存在的属性值就会自动触发__setattr__
# self.key=value # 这就无限递归了,你好好想想
# self.__dict__[key] = value
# self.__dict__[key]=value #应该使用它
# super(Foo, self).__setattr__()
def __delattr__(self, item):
# z
print('----> from delattr')
# del self.item # 无限递归了
self.__dict__.pop(item)
obj = Foo(10)
obj.z
# obj.z = 1 # ----> from setattr
# print(obj.z) # None
del obj.z
__setitem__,__getitem,__delitem__
class Foo(object):
def __init__(self, name):
self.name = name
def __getitem__(self, item):
print(item)
print("我执行了")
print(self.__dict__[item])
def __setitem__(self, key, value):
print("我也执行了")
print(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)
obj = Foo('kevin')
# obj['name']
obj['age'] = 19
print(obj['age'])
del obj['age']
# __call__ 方法
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print('__call__')
return '123'
obj = Foo()
# 123
print(obj()) # 对象加括号 # __call__
反射
# 反射其实就是通过字符串的形式来操作对象的属性
stu.z = 1
class Student():
school ='SH'
def __init__(self, name, age ):
self.name = name
self.age = age
def index(self):
print('Student.index')
stu = Student('jason', 20)
# print(stu.'name')]
# stu.name
getattr() setattr() delattr() hasattr()
1. getattr()
# res=getattr(stu, 'name') # attribute 属性 attr # jason
# res1=getattr(stu, 'age1', 666) # attribute 属性 attr # jason
# res1=getattr(stu, 'age1', 666) # attribute 属性 attr # jason
# print(res)
# print(res1)
# res = getattr(stu, 'index') # index函数的内存地址
# print(res)
# res()
2. setattr()
setattr(stu, 'x', 1)
setattr(stu, 'name', '666') # 如果属性名存在就是修改,不存在就是增加
print(stu.__dict__)
3. delattr()
delattr(stu, 'name')
print(stu.__dict__)
4. hasattr()
print(hasattr(stu, 'index')) # 返回布尔值,只是一个判断是否存在
补充
# 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)
反射的案例
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. 如何捕捉异常
try:
被检测的代码
except 异常类型:
pass
else:
print()
finally:
print()
"""以上结构是我们为了捕捉代码中出现的异常"""
2. 我们自己如何抛出异常:raise
class Animal():
# @abc.abstractmethod
def speak(self):
raise Exception("请先实现speak方法")
class People(Animal):
def speak(self):
pass
# pass
"""主动抛出异常"""
stu = People()
stu.speak()
3. 自定义异常
class MyException(BaseException):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return self.msg
raise MyException("这是异常信息")
标签:__,name,自定义,stu,self,面向对象,print,异常,def
From: https://www.cnblogs.com/huangchunfang/p/17512584.html