pyhon基础之描述符(17)

描述符:
如果一个类中包含了三个魔术方法(getsetdelete)之一或者全部的类这个类就是一个描述符
描述符的作用:
描述符的作用就是对类/对象中某个成员进行详细的管理操作。
数据描述符:(完整)
同时具备三个魔术方法的类就是数据描述符
非数据描述符(不完整):
没有同时具备三个魔术方法的类就是非数据描述符
三个魔术方法:
get():
触发时机:在访问对象成员属性(该成员已经交给描述符管理的时候)的时候触发
作用:设置当前属性获取的值
参数:self 描述符的对象 / 第二个 被管理成员的类的对象 / 第三个 被管理成员的类
返回值:可有可无,有的话就是获取的值
注意事项:无

set():
触发时机:在设置对象成员属性(该成员已经交给描述符管理的时候)的时候触发
作用:对成员的值进行设置管理
参数:self 描述符的对象 / 第二个 被管理成员的类的对象 / 第三个 要设置的值
返回值:无
注意事项:设置值的时候一定要设置当前描述符对象的临时变量

delete():
触发时机:在删除对象成员属性(该成员已经交给描述符管理的时候)的时候触发
作用:对成员的值进行删除管理
参数:self 描述符的对象 / 第二个 被管理成员的类的对象
返回值:无
注意事项:删除值的时候一定要删除当前描述符对象的临时变量

#第一种描述方式:
class MiaoShu():
def init(self):
self.new_name = “王二锤” # 可以看作巫蛊娃娃(只是临时的)
def get(self,obj,cls): # self 是当前对象本身,obj是被描述的类对象,cls是被描述的类
return self.new_name
def set(self, instance, value):
# print(self) #当前类对象
# print(instance) #被描述的类对象
# print(value) # 增加或修改的值
if instance.sex >= 30:
self.new_name = value
elif instance.sex < 30:
self.new_name = “你太小了,不适合自己改名字”
def delete(self,value):
# print(self) # 当前类对象
# print(value) # 被描述的类对象
if value.sex == 30:
del self.new_name
else:
pass

被描述的类

class Human():
name = MiaoShu() # 把Human的name属性交给MiaoShu进行管理
sex = 30
# 成员方法
def run(self):
print(“大锤跑的飞快”)

实例化类

chui = Human()
print(chui.name)
chui.name = 180 # 增加
chui.name = “小锤锤” # 修改
print(chui.name)
del chui.name

print(Human.dict)

print(chui.name)

print(Human.dict)

结果为
王二锤
小锤锤
报错,self.new_name被删除.不存在返回值

描述符的第二种写法(使用property函数)

class Human():
# name = “王大锤”
def init(self):
self.new_name = “王小锤”
# 成员方法
def get_name(self):
return self.new_name
def set_name(self,value):
print(“set被触发了”)
self.new_name = value
def del_name(self):
del self.new_name
name = property(get_name,set_name,del_name) # 顺序:获取,设置,删除
chui = Human()

print(chui.name)

print(chui.dict)

chui.name = “王三锤”

print(chui.dict)

print(chui.name)

del chui.name
print(chui.dict)
print(chui.name)

#第三种方式:
class Human():
def init(self):
self.new_name = “王二妮”
@property # 对成员进行get管理
def name(self):
return self.new_name[0]+"*"+self.new_name[-1]
@name.setter # 对成员进行set管理
def name(self,value):
self.new_name = value
@name.deleter # 对成员进行delete管理
def name(self):
del self.new_name
chui = Human()

print(chui.name)

chui.name = “王大美”

print(chui.name)

del chui.name
print(chui.name)

描述符和属性魔术方法:

属性魔术方法
getattribute
getattr
setattr
delattr
【针对当前类/对象所有成员的管理,属性魔术方法仅对当前类有效】

描述符(是一个类):
get
set
delete
【仅仅针对类/对象某一个成员的设置,描述符可对不同的类使用】
什么是抽象类?(了解即可)
不完整的一种类。
具有抽象方法的类就是抽象类。(只要有一个抽象方法也可)
什么是抽象方法?
不完整的方法
没有方法体的方法就是抽象方法。
什么是元类?
元类就是用来制作类的类。
正常情况下所有类的元类默认都是type
如何查看一个类的元类
类.class
type(类)

class Father():
pass
class Son(Father):
pass
print(Father.class)
print(Son.class)
print(type(Father))
print(object.class)

#结果都是type
查询数据类型
type(对象)
对象.class
注意:正常情况下type是系统默认的元类
使用抽象类:
import abc
#把类变成抽象类
class 类名(metaclass=abc.ABCMeta)
#把对象方法变成抽象对象方法
@abc.abstractmethod
方法体必须要pass
#把类方法变成抽象类方法
@abc.abstractclassmethod
#把绑定类的方法变成抽象的绑定类的方法
@abc.abstractmethod
#把静态方法变成抽象的静态方法
@abc.abstractstaticmethod
抽象类的特征:
1.抽象类不能实例化使用
2.抽象类中可以存在抽象方法,也可以存在正常的方法
3.抽象类中可以添加成员属性
4.抽象类的使用方式就是被其他类继承。
5.其他类继承了抽象类并且实现了抽象类的所有抽象方法之后就可以实例化该类
抽象类的实际作用:
1.制定开发程序规范
2.协同程序开发,加速开发效率

例:
#导入抽象类的功能模块
import abc
class User(metaclass = abc.ABCMeta):#注意制作抽象类必须另外指定元类
#添加用户的方法 对象方法 -> 抽象的对象方法 【小赵】
@abc.abstractmethod
def user_add(self):
pass
#修改用户的方法 类方法 -> 抽象的类方法 【小钱】
@abc.abstractclassmethod
def user_update(cls):
pass
#删除用户的方法 绑定类的方法 - > 抽象的绑定类的方法 【小孙】
@abc.abstractmethod
def user_del():
pass
#查找用户的方法 静态方法 -> 抽象的静态方法 【小李】
@abc.abstractstaticmethod
def user_find():
pass
#抽象类中可以有正常的方法 【自己】
def user_lock(self):
print(‘封禁用户的方法’)
#小赵的工作 [可以在一个单独的文件中开发]
class XZUser(User):
# 添加用户的方法 对象方法 【小赵】
def user_add(self):
print(‘添加用户的方法-小赵完成的’)
#小钱的工作[可以在一个单独的文件中开发]
class XQUser(XZUser):
# 修改用户的方法 类方法 【小钱】
@classmethod
def user_update(cls):
print(‘设置用户的方法-小钱完成的’)
#小孙的工作[可以在一个单独的文件中开发]
class XSUser(XQUser):
# 删除用户的方法 绑定类的方法【小孙】
def user_del():
print(‘删除用户的方法-小孙完成的’)
#小李的工作[可以在一个单独的文件中开发]
class XLUser(XSUser):
# 查找用户的方法 静态方法 -> 抽象的静态方法 【小李】
@staticmethod
def user_find():
print(‘查找用户的方法-小李完成的’)

#这里可以使用小李的类
u = XLUser()
#调用方法
u.user_lock()
u.user_add()
XLUser.user_update()
XLUser.user_del()
u.user_find()
在python中 任何内容都是对象—万物皆对象
类是对象,对象是对象,数据是对象… 任何内容都是基于object对象创建的

其中 type的父类是object
object的类型(元类)是type
所以这是鸡和鸡蛋的问题

可以认为object是制作任何内容原材料,而type是最底层的分类类型
人是分类 type

人肉是材料 object

任何人(内容)都是人肉【object】组成的

男人,女人,黑人,白人,黄人 都属于人【type】这个分类

人【type】也是人肉【object】做的

人肉【object】也属于人【type】的分类下

异常?
简单的说异常就是程序运行过程中出现的各种各样的错误。
异常处理:
解决或者处理我们的异常问题。
错误与异常的分类:
BaseException 所有异常的基类*
AssertError 断言语句(assert)失败
AttributeError 尝试访问未知的对象属性
EOFError 用户输入文件末尾标志EOF(Ctrl+d)
FloatingPointError 浮点计算错误
GeneratorExit generator.close()方法被调用的时候
ImportError 导入模块失败的时候*
IndexError 索引超出序列的范围*
KeyError 字典中查找一个不存在的关键字*
KeyboardInterrupt 用户输入中断键(Ctrl+c)
MemoryError 内存溢出(可通过删除对象释放内存)
NameError 尝试访问一个不存在的变量*
NotImplementedError 尚未实现的方法
OSError 操作系统产生的异常(例如打开一个不存在的文件)*
OverflowError 数值运算超出最大限制
ReferenceError 弱引用(weak reference)试图访问一个已经被垃圾回收机制回收了的对象
RuntimeError 一般的运行时错误
StopIteration 迭代器没有更多的值*
SyntaxError Python的语法错误*
IndentationError 缩进错误*
TabError Tab和空格混合使用*
SystemError Python编译器系统错误
SystemExit Python编译器进程被关闭
TypeError 不同类型间的无效操作*
UnboundLocalError 访问一个未初始化的本地变量(NameError的子类)
UnicodeError Unicode相关的错误(ValueError的子类)
UnicodeEncodeError Unicode编码时的错误(UnicodeError的子类)
UnicodeDecodeError Unicode解码时的错误(UnicodeError的子类)
UnicodeTranslateError Unicode转换时的错误(UnicodeError的子类)
ValueError 传入无效的参数
ZeroDivisionError 除数为零
异常处理专用语法(流程控制中的一种):
格式1:
try:
尝试执行代码
except:
处理或者显示错误

try 区间有错误时执行的代码

try:
print(“hello”)
print(“world”)
print(name)
except:
print(“错误出现!”)

格式2:
try:
尝试执行代码
except 错误类型:
处理或者显示错误

第二种格式:精准的控制错误类型

try:
print(nihao)
except NameError:
print(“尝试访问不存在的变量出错!”)

格式3:
try:
尝试执行代码
except 错误类型 as 变量:
处理或者显示错误

第三种格式:显示系统提示的错误异常原因

try:
print(nihao)
except NameError as NF:
print(“尝试访问不存在的变量出错”)
print(NF)

结果为:尝试访问不存在的变量出错
name ‘nihao’ is not defined

格式4:
try:
尝试执行代码
except 错误类型 as 变量:
处理或者显示错误
except 错误类型 as 变量:
处理或者显示错误
except 错误类型 as 变量:
处理或者显示错误

#第四种:多个except同时出现(except后面就必须有错误异常名称)
try:
print([1,2,3][4])
except BaseException:
print(“出错了!”)
except NameError:
print(“尝试访问不存在的变量出错”)
except IndexError:
print(“索引超出范围报错!”)
except ZeroDivisionError:
print(“除数为零报错!”)

结果为:出错了

格式5:
try:
尝试执行代码
except 错误类型 as 变量:
处理或者显示错误
except 错误类型 as 变量:
处理或者显示错误
except 错误类型 as 变量:
处理或者显示错误

except:
处理或者显示错误

第5种:多个except同时出现(最后一个except可以不写错误异常名称)

try:
print([1,2,3][4])
except KeyError:
print(“出错了!”)
except NameError:
print(“尝试访问不存在的变量出错”)
except ImportError:
print(“索引超出范围报错!”)
except ZeroDivisionError:
print(“除数为零报错!”)
except:
print(“不管是啥原因,反正出错了!”)

结果为:
不管是啥原因,反正出错了!

格式6:
try:
尝试执行代码
except 错误类型 as 变量:
处理或者显示错误
except 错误类型 as 变量:
处理或者显示错误
except 错误类型 as 变量:
处理或者显示错误

except:
处理或者显示错误
else:
程序没有异常的时候执行的区域

第6种 try ,except,else 程序无异常会执行else区间 try:

print([1,2,3])  #1

except KeyError:
print(“出错了!”) #2
except NameError:
print(“尝试访问不存在的变量出错”) #3
except ImportError:
print(“索引超出范围报错!”) #4
except ZeroDivisionError:
print(“除数为零报错!”)#5
except:
print(“不管是啥原因,反正出错了!”)#6
else:
print(“程序并没有任何的异常出现!”)#7

结果为:[1, 2, 3]
程序并没有任何的异常出现!

格式7:
try:
尝试执行代码
except 错误类型 as 变量:
处理或者显示错误
except 错误类型 as 变量:
处理或者显示错误
except 错误类型 as 变量:
处理或者显示错误

except:
处理或者显示错误
else:
程序没有异常的时候执行的区域
finally:
无论程序执行是否出现异常都会执行的区域

try:
print([1,2,3][6]) #1
except KeyError:
print(“出错了!”) #2
except NameError as NE:
print(“尝试访问不存在的变量出错”) #3
except IndexError as IE:
print(“索引超出范围报错!”) #4
except ZeroDivisionError:
print(“除数为零报错!”)#5
except:
print(“不管是啥原因,反正出错了!”)#6
else:
print(“程序并没有任何的异常出现!”)#7
finally:
print(“错误与异常处理完毕!”) #8

结果为:索引超出范围报错!
错误与异常处理完毕!

注意:try…except 不可以当作if…else使用
raise语句:
主动触发异常

raise 异常类(参数)
注:raise语句主动抛出异常,参数为可选。不选为空,选择即为异常的名称。
如:
try:
raise NameError(“名称错误”)
except NameError as f:
print(f)

结果为:名称错误
自定义异常类型:

class 异常类型名称(Exception):
类成员…
类成员…
如何使用自定义异常类:

自定义异常类:一般继承Exception,也可继承baseException
raise 异常对象(“异常描述”)

例:
class WenGuang(BaseException):
pass
guang = WenGuang()
guang.name = “文广”
print(guang.name)
try:
raise WenGuang(“异常类错误!”)
except WenGuang as WG:
print(WG)

结果为 异常类报错

你可能感兴趣的:(python基础)