面向对象高阶 内置成员
获取当前类\对象的所属成员,返回一个字典包含类或对象的成员
获取类的文档信息,就是定义类后对类的一个说明
获取类名称,结果返回字符串
获取类所在的文件名称,如果是当前文件就会返回main
获取当前类的父类或者父类列表列表
获取类的继承关系
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 class A (): pass class B (): pass class Demo (A, B): """ 这是类的说明文档 """ name = None age = None def func (self ): print ('这是一个方法' ) res = Demo.__dict__ print ( res) d = Demo() res = d.__dict__ print (res) res = Demo.__doc__ print (res)res = d.__doc__ print (res)res = Demo.__name__ print (res) res = Demo.__module__ print (res) res = Demo.__base__ print (res) res = Demo.__bases__ print (res) print (Demo.mro()) print (Demo.__mro__)
方法的分类 对象方法 在类中定义的方法,含有 self 参数 含有 self 的方法,只能使用对象进行调用 该方法会把调用的对象传递进来
1 2 3 4 5 6 7 8 9 10 class Demo (): def fun (self ): print (self ) print ('this is func' ) d = Demo() d.fun()
类方法 在类中定义的方法,使用了装饰器@classmethod 进行装饰的类 方法中有 cls 这个形参,不需要实例化对象就可以直接用类调用的方法 会把调用这个方法的类传递进来
1 2 3 4 5 6 7 8 9 10 11 class Cdemo (): @classmethod def fun (cls ): print (cls) print ('this is class method' ) Cdemo.fun()
绑定类方法 绑定类方法就是在类中,不带有形参 self 的一个方法 调用的时候直接使用类调用,无法使用对象调用 不会传递任何参数进来
1 2 3 4 5 6 7 8 class Bdemo (): def func (): print ('this is bind class func' ) Bdemo.func()
静态方法 在类中定义的方法,使用了装饰器@staticmethod 进行装饰的类 类中,不带有形参 self 的一个方法,也没有其他参数 可以使用类或者对象直接调用 不会传递任何参数
静态方法只是定义在类范围内的一个函数而已
1 2 3 4 5 6 7 8 9 10 class Sdemo (): @staticmethod def func (): print ('this is a static method' ) s = Sdemo() s.func() Sdemo.func()
常用函数
检测一个类是否为另一个类的子类
检测一个对象是否是一个类的实例化
检测一个类/对象是否具有一个成员属性
获取类/对象成员的值
设置类/对象成员的值
setattr(obj/cls,attr,value)
删除类/对象的成员属性
dir() 获取当前对象所可以访问的成员列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class A (): def hello (self ): print ('hello' ) class B (A ): pass class C (A ): pass class D (B, C): name = None def get_hello (self ): print ('hello' ) print (issubclass (D, B)) d = D() print (isinstance (d, D)) print (isinstance (d, B)) print (hasattr (d, 'hello' )) print (hasattr (d, 'get_hello' )) print (hasattr (d, 'name' )) res = getattr (d, 'name' ) print (res) setattr (d, 'name' , 'zachary' )print (d.name) delattr (d,'name' )print (d.name) res = dir (d) print (res)
魔术方法 魔术方法就是不需要手动调用就可以自动执行的方法
init 初始化方法
触发机制:当实例化对象之后就会立即触发的方法
作用:为当前创建的对象完成一些初始化的操作,比如:成员属性的赋值,方法的调用,打开或创建一些资源
参数:一个 self,接受当前对象,其他参数根据需求进行定义即可
返回值:无
注意事项:无
new 构造方法构造一个对象的过程是:
1 2 3 4 person = Person("Jack" ) 实际上做了两件事情 1. person = object .__new__(Person, "Jack" )2. person.__init__("Jack" )
触发机制:实例化对象时自动触发(在init 之前触发)
作用:管理控制对象创建的过程
参数:一个 cls 接受当前类,其他参数根据初始化方法的参数进行决定
返回值:必须返回 object.new (cls)进行对象的创建,如果没有返回值,则实例化的对象的结果为 None
注意事项:
new 方法的参数和init 方法的参数要保持一致,除了第一个参数
必须返回 object.new (cls)进行对象的创建,如果没有返回值,则实例化对象的结果为 None
通常情况下,定义了new ,就不用再定义init 方法了
应用场景:设计模式中的单例设计模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Square (int ): def __new__ (cls,value:int ): return super ().__new__(cls,value**2 ) num = Square(2 ) print (num)print (type (num))print (isinstance (num, int ))class Student : def __new__ (cls,name,gender ): obj = super ().__new__(cls) obj.name = name obj.gender = gender return obj student = Student("zachary" ,"male" ) print (student.name)print (student.gender)
del 析构方法
触发机制:当该类对象被销毁时,自动触发
作用:关闭或释放对象创建时打开或创建的一些资源
参数:一个 self,接受当前对象
返回值:无
注意事项:无
call
触发机制:把对象当做函数直接调用时自动触发
作用:一般用于归纳类或对象的操作步骤,方便调用
参数:一个 self 接收当前对象,其他参数根据调用需求确定
返回值:可有可无
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Person (): def __new__ (cls, *args, **kwargs ): print ('触发了构造方法' ) print (args) return object .__new__(cls) def __init__ (self, name, age, gender ): print ('触发了初始化方法' ) self .name = name self .age = age self .gender = gender def __call__ (self, *args, **kwargs ): print ('你把对象当成了函数进行调用' ) def __del__ (self ): print ('触发了析构方法' ) duanduan = Person('duandaun' , 23 , 'female' ) duanduan()
len 可以代替对象使用 len 函数,并返回一个指定的整型
触发机制:当使用 len 函数去检测当前对象的时候自动触发
作用:可以使用 len 函数检测当前对象中某个数据的信息
参数:一个 self 接收当前对象
返回值:必须有,并且必须是一个整数
注意事项:len 要获取什么属性的值,就在返回值中返回那个属性的长度即可
str 可以代替对象进行 str 或者 print 的字符串信息返回
触发机制:当使用 str 或者 print 函数对对象进行操作时自动触发
作用:代码对象进行字符串的返回,可以自定义打印的信息;该描述面向用户
参数:一个 self,接受当前对象
返回值:必须有,而且必须是字符串类型的值
repr
触发机制:在使用 repr 方法对当前对象进行转换时自动触发,某种情况 print 也可以触发
作用:可以设置 repr 函数操作对象的结果;该描述的主要目标是机器或者开发者
参数:一个 self 接受当前对象
返回值:必须有,而且必须是字符串类型的值
注意:正常情况下,如果没有str 这个魔术方法,repr 方法就会代替str 魔术方法,可以使用 print 进行触发
bool
触发机制:当使用 bool 函数转换当前对象时,自动触发
作用:可以代替对象进行布尔类型的转换,可以转换任何数据
参数:一个 self 接收对象
返回值:必须是一个布尔类型的返回值,如果没有实现bool 方法,会去掉用len 的结果求解 bool 值
eq
触发机制:当使用==比较两个对象的内容是否相同的时候
作用:对比两个对象是否相等的逻辑
参数:一个 self 接收对象,other 接收另一个对象
返回值:必须有 Bool 类型
hash
触发机制:使用hash()方法 或者 将该对象加入到 set、dict 等需要调用 hash()方法的时候会调用
作用:根据对象生成 hash 值的逻辑
参数:一个 self 接收对象
返回值:hash 值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 class Demo (): listurl = [] def __len__ (self ): return len (self .listurl) def __str__ (self ): return '这是当前脚本中的一个对象' def __repr__ (self ): return '这是一个对象' obj = Demo() res = len (obj) print (res) print (obj) res = str (obj) print (res) print (obj) res = repr (obj) print (res) res = bool (obj) print (res) class MyDate (): def __init__ (self,year,month,day ): self .year = year self .month = month self .day = day def __eq__ (self,other ): if not isinstance (other,MyDate): return False return self .year == other.year and self .month == other.month and self .day == other.day def __hash__ (self ): print ("__hash__被调用了" ) return hash (self .year + self .month * 41 + self .day * 41 ) mydate1 = MyDate(2023 ,1 ,4 ) mydate2 = MyDate(2023 ,1 ,4 ) mydate3 = mydate1 print (mydate1 is mydate2)print (mydate1 is mydate3)print (mydate1 == mydate2)print (mydate1 == mydate3)test_set = set () test_set.add(mydate1) print (hash (mydate2))
str 与 repr str 和 repr 函数都能够把其他类型的数据转化为字符串类型 str 函数会把对象 转为 更适合人类阅读的形式 repr 函数会把对象 转为 更适合解释器读取的形式 如果数据对象并没有明显的区别的话,str 和 repr 结果是一样的
成员相关魔术方法
getattribute (self, item)
触发机制:当访问对象成员时,自动触发,无论当前成员是否存在,也无论当前成员是否有值
作用:可以在获取对象成员时,对数据进行一些处理
返回值:可有可无,返回的值就是访问的结果
注意事项:
在当前的魔术方法中,禁止使用 对象.成员 的方式进行成员访问,会触发递归
如果想要在当前魔术方法中访问对象的成员必须使用 object 来进行访问
格式:
object.getattribute (self, item)
getattr
触发机制:当访问对象中不存在的成员时,自动触发
作用:防止访问不存在的成员时报错,也可以为不存在的成员进行赋值操作
参数:一个 self 接收当前对象,一个 item 接收当前访问的成员名称
返回值:可有可无
注意事项:
如果有getattribute 存在,就会无法使用getattr ,会直接调用到getattribute
也要注意,不要在当前的方法中再次去访问这个不存在的成员,会触发递归操作
setattr
触发机制:当给对象的成员进行赋值操作时会自动触发(包括添加、修改)
作用:可以限制或管理对象成员的添加和修改操作
参数:1.self 接收当前对象 2.设置的成员名 3.设置的成员值
返回值:无
注意事项:
在当前的魔术方法中禁止给当前对象的成员直接进行赋值操作,会触发递归操作,
如果想要给当前对象的成员进行赋值,需要借助 object
格式:object.setattr (self,key,value)
该方法中如果没有给对象成员进行赋值,那么对象成员赋值失败
delattr
触发机制:当删除对象成员时自动触发
作用:可以去限制对象成员的删除,还可以删除不存在成员时的报错
参数:1.self 接收当前对象 2.item 删除的成员名称
返回值:无
注意事项:
在当前魔术方法中禁止直接删除对象的成员,会触发递归操作
如果想要删除当前对象的成员,那么需要借助 object
格式:object.delattr (self,item)
访问一个成员的顺序
调用 getattribute 魔术方法
调用数据描述符
调用当前对象的成员属性
调用当前类的成员
调用非数据描述符
调用父类的成员
调用getattr 魔术方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 class Person (): name = '名字' age = '年龄' gender = '性别' def __init__ (self, name, age, gender ): self .name = name self .age = age self .gender = gender def say (self ): print ('聊一聊,倾诉一下' ) def sing (self ): print ('庄先生,高歌一曲' ) def __getattribute__ (self, item ): try : res = object .__getattribute__(self , item) return res[0 ] + '*' + res[-1 ] except : return False def __getattr__ (self, item ): print (item) return False def __setattr__ (self, key, value ): object .__setattr__(self , key, value) def __delattr__ (self, item ): object .__delattr__(self , item) duan = Person('duanduan' , 23 , 'female' ) print (duan.name) print (duan.salary) print (duan.name) print (duan.salary)duan.salary = 10000 print (duan.salary) del duan.salaryprint (duan.salary) del duan.nameprint (duan.name)
描述符与 property 当一个类中,包含了三个魔术方法(get ,set ,delete )之一,或者全部,那么这个类就被称为描述符类
基本语法 描述符的作用:
描述符的作用就是对一个类中的某个成员进行一个详细的管理操作(获取、赋值、删除)
描述符就是代理了一个类中的成员的操作,描述符属于类,只能定义为类的属性
一个类中的成员的值是另一个描述符类的对象() 那么当对这个类中的成员进行操作时,可以理解为就是对另一个对象的操作 使用格式:把当前的描述符类赋值给一个需要代理的类中的成员属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class PersonName (): __name = 'duanduan' def __get__ (self, instance, owner ): return self .__name def __set__ (self, instance, value ): self .__name = value def __delete__ (self, instance ): del self .__name class Person (): name = PersonName() duan = Person() print (duan.name) duan.name = 'duanxiaozhu' print (duan.name) del duan.nameprint (duan.name)
实际上真正的用法应该是下面这个例子,还需要额外使用一个
__set_name__(self, owner, name)方法 给属性赋值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class PersonName : def __set_name__ (self, owner, name ): self .__property_name = name def __set__ (self, instance, value ): if not isinstance (value, str ): raise Exception(f"{self.__property_name} is not a str type" ) if len (value) == 0 : raise Exception(f"{self.__property_name} is empty" ) instance.__dict__[self .__property_name] = value def __get__ (self, instance, owner ): if self .__property_name in instance.__dict__: return instance.__dict__[self .__property_name] return None
应用案例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 ''' 定义一个学生类,需要记录,学员的id、名字、分数 解决方法: 1. 在__init__方法中检测当前分数范围的合法性 但是这个方法只能在初始化的时候有效,之后修改的话就无效了 2. 定义一个__setattr__的魔术方法进行检测 检测给分数进行赋值的时候的一个合法性 假如 学员的分数不止一个时怎么办,比如 语文分数、数学分数、英语分数 甚至类中的代码比较多的情况 解决方法: 3. 可以使用描述符来代理我们分数这个属性 ''' class Student (): def __init__ (self,id ,name,score ): self .id = id self .name = name if score >= 0 and score <=100 : self .score = score else : print ('当前分数出错啦' ) def returnShe (self ): info = f''' 学号:{self.id } 姓名:{self.name} 分数:{self.score} ''' print (info) def __setattr__ (self, key, value ): if key == 'score' : if value >= 0 and value <= 100 : object .__setattr__(self ,key,value) else : print ('当前分数出错啦' ) else : object .__setattr__(self ,key,value) duan = Student(2022 ,'duanduan' ,100 ) duan.returnShe() duan.score = 1000 duan.returnShe() class Score (): def __set__ (self, instance, value ): if value >= 0 and value <= 100 : self .__score = value else : print ('当前分数出错啦' ) def __get__ (self, instance, owner ): return self .__score def __delete__ (self, instance ): pass class Student (): score = Score() def __init__ (self,id ,name,score ): self .id = id self .name = name self .score = score def returnShe (self ): info = f''' 学号:{self.id } 姓名:{self.name} 分数:{self.score} ''' print (info) duan = Student(2022 ,'duanduan' ,100 ) duan.returnShe() duan.score = 1000 duan.returnShe()
三种定义方式
第一种 1 2 3 4 5 6 7 8 9 10 11 12 class ScoreManage (): def __get__ (self, instance, owner ): pass def __set__ (self, instance, value ): pass def __delete__ (self, instance ): pass class Student (): score = ScoreManage()
第二种 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Studebnt (): def getscore (self ): print ('getscore' ) def setscore (self, value ): print ('setscore' , value) def deletescore (self ): print ('deletescore' ) score = property (getscore, setscore, deletescore) xs = Studebnt() print (xs.score)xs.score = 100 print (xs.score)del xs.score
第三种 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Student (): __score = None @property def score (self ): print ('get' ) return self .__score @score.setter def score (self, value ): print ('set' ) self .__score = value @score.deleter def score (self ): print ('delete' ) del self .__score xs = Student() print (xs.score)xs.score = 100 print (xs.score)del xs.score
设计模式 设计模式是前人为了完成某个功能或需求,根据经验和总结,对实现的代码步骤和代码设计进行了总结和归纳。成为了实现某种需求的经典模式 设计模式并不是固定的,而是一种面向对象编程的设计
单例(单态)设计模式 在当前脚本中,同一个类只能创建出一个对象去使用,这种情况就称为单例(单态)
Python 中的单例模式设计思路,
1、需要有一个方法,可以去控制当前对象的创建
2、需要有一个标识来存储和表示是否有对象
3、在创建对象的方法中去检测和判断是否有对象?
如果没有对象,则创建对象,并且把对象存储起来
如果存储的是对象,则直接返回对象,就不需要创建新的对象了
这个代码很重要 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Demo (): __obj = None def __new__ (cls, *args, **kwargs ): if not cls.__obj: cls.__obj = object .__new__(cls) return cls.__obj a = Demo() b = Demo() print (a) print (b)
使用装饰器来实现的话
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def singleton (cls ): _obj = {} def inner (*args, **kwargs ): if cls in _obj: return _obj[cls] obj = cls(*args, **kwargs) _obj[cls] = obj return obj return inner @singleton class Demo : pass a = Demo() b = Demo() print (a is b)
装饰器模式-2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def singleton (cls ): def inner (): if hasattr (cls,"__obj" ): return getattr (cls,"__obj" ) obj = cls() setattr (cls,"__obj" ,obj) return obj return inner @singleton class Demo : pass a = Demo() b = Demo() print (a is b)
装饰器模式-3,使用元类来设计
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class SingletonMeta (type ): def __call__ (cls, *args, **kwargs ): if hasattr (cls,"__obj" ): return getattr (cls,"__obj" ) obj = super ().__call__(*args, **kwargs) setattr (cls,"__obj" ,obj) return obj class Demo (metaclasss=SingletonMeta): pass a = Demo() b = Demo() print (a is b)
mixin 混合设计模式 继承需要一个必要的前提,继承应该是一个‘is-a’的关系 例如:苹果可以去继承水果,因为苹果是一个水果
Minin 表示混合
Minin 必须是表示一种功能,而不是一个对象
Minin 的功能必须单一,如果有多个功能,那就多定义 Minin 类
Python 中的 Minin 是通过多继承实现的
Minin 这个类通常不单独使用,而是混合到其他类中,去增加功能
Minin 类不依赖子类的实现,即便子类没有继承这个 Minin,子类也能正常运行,就是可能会缺少了一些功能
使用 Minin 混合类的好处
在不对类的内容修改的前提下,扩展了类的功能
Minin 混合类为了提高代码的重用性,使得代码结构更加简单清晰
可以根据开发需求任意调整功能(创建新的 Minin 类)
避免设计多层次的复杂继承关系
解决方案使用的还是多继承,但是给飞行器这个类的名称定义成为一个 Minin 混合类
这样的一个 Minin 混合类,功能单一、并且不会单独使用:只有一个飞行器的功能,在继承的时候不会单一继承这一个,作为一个扩展的功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class vehicle (): def huo (self ): print ('运输货物' ) def ren (self ): print ('搭载乘客' ) class flyingMixin (): def fly (self ): print ('可以起飞啦' ) class cart (vehicle ): pass class airplane (vehicle,flyingMixin): pass class helicopter (airplane,flyingMixin): pass
实现一个具体的列子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class ItemMixin : def __getitem__ (self, key ): return self .__dict__[key] def __setitem__ (self, key, value ): self .__dict__[key] = value class Car (ItemMixin ): def __init__ (self, origin, auto ): self .origin = origin self .auto = auto car = Car("Germany" , True ) print (car["origin" ])
练习:把一个对象转换成 dict 和 json 格式,使用 mixin 设计模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class DictMixin : def to_dict (self ): return self .__dictConvert(self .__dict__) def __dictConvert (self, dicAttrs: dict ): resDict = {} for key, value in dicAttrs.items(): resDict[key] = self .__valueConvert(value) return resDict def __valueConvert (self, value ): if isinstance (value, DictMixin): return value.to_dict() elif isinstance (value, dict ): return self .__dictConvert(value) elif isinstance (value, list ): return [self .__valueConvert(i) fot i in list ] elif hasattr (value,'__dict__): return self.__dictConvert(value) else: return value class JSONMixin: def to_json(self): return json.dumps(self.to_dict()) class Car(DictMixin, JSONMixin): def __init__(self, origin, auto): self.origin = origin self.auto = auto car = Car("Germany",True) print(car.to_dict()) print(car.to_json())
抽象类
抽象类是一个特殊的类
抽象类不能用,不能直接实例化成为一个对象
抽象类中包含了抽象方法,抽象方法就是没有实现的代码的方法
抽象类需要子类继承,并重写父类的抽象方法,才可以使用
如果要定义一个抽象类,需要继承metaclass=abc.ABCMeta类 或者 ABC
如果要定义一个抽象方法,需要使用装饰器进行装饰@abc.abstractmethod
抽象类不能直接实例化
想要实现一个抽象类,需要定义一个子类去继承抽象类,然后实现抽象类中的抽象方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 import abcclass AbsCls (metaclass=abc.ABCMeta): @abc.abstractmethod def absmethod (self ): pass def othermethod (self ): print ('这是一个实现了的方法' ) class sonclass (AbsCls ): def absmethod (self ): print ('son实现了抽象类的抽象方法' ) class daughterclass (AbsCls ): def absmethod (self ): print ('daughter实现了抽象类的抽象方法' ) def method_call (abscls: AbsCls ): abscls.absmethod() obj = sonclass() obj.absmethod() obj.othermethod() son = sonclass() daughter = daughterclass() method_call(son) method_call(daughter)
枚举 基本用法 作用:代码中的数值,不便于阅读和查错
1 2 3 class Student : def __init__ (self ): self .gender = 1
定义枚举类:通过继承 enum.Enum实现一个枚举类
可以通过字符串 用[]获取到对应的枚举类型
可通过整数类型转换 用()获取到对应的枚举类型
枚举类本身是可以迭代的(比如 下拉列表,需要获取全部选项)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 from enum import Enumclass Gender (Enum ): MALE = 1 FEMALE = 2 class Student : def __init__ (self ): self .gender = Gender.MALE print (Gender.MALE.name)print (Gender.MALE.value)gender_str = "MALE" student = Student() student.gender = Gender[gender_str] print (student.gender)gender_int = 2 student.gender = Gender(gender_int) print (student.gender)for gender in Gender: print (gender)
枚举成员的别名
枚举类中的多个成员具有同一个 value 时,只有一个能成为主要成员,其余是别名
可以通过__members__获取枚举类的所有成员
唯一枚举装饰器 @enum.unique(为了避免 不允许重复 value 的情况下出错,比如有时候复制粘贴会写出两个相同 value 的枚举 然后忘记修改的情况,可以使用唯一枚举装饰器进行处理)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class ResStatus (Enum ): SUCCESS = 1 OK = 1 FAIL = 2 NO = 2 for rs in ResStatus: print (rs.name) print (ResStatus.__members__)print (ResStatus.SUCCESS == ResStatus.OK)print (ResStatus.SUCCESS is ResStatus.OK)@num.unique class Status (Enum ): SUCCESS = 1 OK = 1 FAIL = 2 NO = 2
枚举的扩展
__str__
1 2 3 4 5 6 7 8 9 10 class ResStatus (Enum ): SUCCESS = 1 OK = 1 FAIL = 2 NO = 2 def __str__ (self ): print (f"{self.name} ({self.value} )" ) print (ResStatus.OK)
__eq__
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class ResStatus (Enum ): SUCCESS = 1 OK = 1 FAIL = 2 NO = 2 def __eq__ (self,other ): if isinstance (other,int ): return self .value == other if isinstance (other,str ): return self .name == other.upper() if isinstance (other,ResStatus): return self is other return False print (ResStatus.OK == 1 )
__lt__
需要使用@total_ordering
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @total_ordering class OrderOfProcess (Enum ): START = 1 PROCESSING = 2 TEST = 3 END = 4 def __lt__ (self ): if isinstance (other,int ): return self .value < other if isinstance (other,OrderOfProcess): return self .value < other.value return False print (OrderOfProcess.PROCESSING < 2 )print (OrderOfProcess.END < OrderOfProcess.TEST)
auto()
按顺序给枚举成员赋值
1 2 3 class ResStatus (Enum ): SUCCESS = auto() FAIL = auto()
更新: 2024-01-11 22:37:47 原文: https://www.yuque.com/zacharyblock/cx2om6/yke47fm8vxrh2w6g
Author:
Zachary Block
Permalink:
http://blockzachary.cn/blog/3938337518/
License:
Copyright (c) 2019 CC-BY-NC-4.0 LICENSE