面向对象进阶-2 所有类均继承object
1.类的嵌套:
函数:参数可以是任意类型。
字典:对象和类都可以做字典的key和value
继承的查找关系
对象和类都可以做字典的key和value- class StackConfig(object):
- pass
- class UserConfig(StackConfig):
- pass
- class AdminSite(object):
- def __init__(self):
- self._register = {}
- def registry(self,key,arg=StackConfig):
- self._register[key] = arg
- def run(self):
- for key,value in self._register.items():
- obj = value()
- print(key,obj)
- site = AdminSite()
- site.registry(1)
- site.registry(2,StackConfig)
- site.registry(3,UserConfig)
- site.run()
- >>>
- 1 <__main__.StackConfig object at 0x000002ABEEE3AB08>
- 2 <__main__.StackConfig object at 0x000002ABEEE3ABC8>
- 3 <__main__.UserConfig object at 0x000002ABEEE3AB88>
复制代码
2.特殊成员 特殊成员:就是为了能够快速实现执行某些方法而生
__init___: 初始化方法:对对象的属性进行初始化
__new__: 构造方法: 创建一个空对象
由于所有类均继承object object中含有__new__ 所以创建类的对像士实际上是先__new__再__init__
__call__: 让类的实例可以像函数一样被调用 直接用 实例名(参数) 调用,等同于执行 实例名.__call__(参数) - class Foo:
- def __init__(self):
- self.__content = 0
- def __call__(self):
- self.__content+=1
- return self.__content
- obj = Foo()
- print(obj()) #1
- print(obj()) #2
复制代码 __str__: 只有在打印对象时,会自动化调用此方法,并将其返回值在页面显示出来
__str__ 方法需要返回字符串
简单说:想让 print(对象) 输出有意义的信息,就用 __str__ 定义规则- class User(object):
- def __init__(self,name,email):
- self.name = name
- self.email = email
- def __str__(self):
- return "%s %s" %(self.name,self.email,)
- user_list = [User('二狗','2g@qq.com'),User('二蛋','2d@qq.com'),User('狗蛋','xx@qq.com')]
- for item in user_list:
- print(item)
复制代码 __dict__: 打印对象中封装的所有值- class Foo:
- def __init__(self,name,age):
- self.name = name
- self.age = age
- obj = Foo('guohan',22)
- print(obj.__dict__)
复制代码 __add__: 用于定义对象的 “加法运算” 逻辑,给自定义类 “赋能”,让它能像数字、字符串那样用 + 运算符
当使用 + 运算符时,Python 会自动调用该方法- class info:
- def __init__(self,x,y):
- self.x = x
- self.y = y
- class Point:
- def __init__(self, x, y):
- self.x = x # x轴坐标
- self.y = y # y轴坐标
- # 重写 __add__,定义 Point 对象的加法逻辑:x相加,y相加
- def __add__(self, other):
- # 先判断 other 是否为 Point 类型,避免非法运算
- if isinstance(other, Point):
- # 返回新的 Point 实例(不修改原对象)
- return Point(self.x + other.x, self.y + other.y)
- # 若 other 类型不支持,抛出错误(符合 Python 内置类型的行为)
- raise TypeError(f"不支持 {type(other)} 类型与 Point 类型相加")
- # 使用 + 运算,自动调用 __add__
- try:
- p1 = Point(1, 2)
- p2 = info(3, 4)
- p3 = p1 + p2 # 等价于 p1.__add__(p2)
- print(p3.x, p3.y)
- except Exception as e:
- print(f'失败原因:{e}') #失败原因:不支持 <class '__main__.info'> 类型与 Point 类型相加
复制代码 __len__: 自定义 “长度” 逻辑
当对对象使用 len() 函数时,Python 会自动调用 __len__ 方法,返回对象的 “长度”- class Students:
- def __init__(self):
- self.list = []
- def add(self,name):
- self.list.append(name)
- def __len__(self):
- return len(self.list)
- obj1 = Students()
- obj1.add('guahan')
- obj1.add('gh')
- print(len(obj1))>>>2
复制代码 __eq__: 自定义 “相等” 逻辑 返回布尔类型
当对两个对象使用 == 运算符时,Python 会自动调用 __eq__ 方法,判断两个对象是否 “相等”- class Students:
- def __init__(self,name):
- self.name = name
- class info:
- def __init__(self,name):
- self.name = name
- def __eq__(self,other):
- if isinstance(other,info):
- return self.name == other.name
- raise Exception('对象类型不匹配')
- try:
- obj1 = info('guohan')
- obj2 = Students('guohan')
- print(obj1 == obj2)
- except Exception as e:
- print(f'比较失败原因:{e}')
- >>>比较失败原因:对象类型不匹配
- self:代表当前对象(比如 obj1)。
- other:代表被比较的另一个对象(比如 obj2)。
- self.name:当前对象的 name 属性(比如 obj1.name 是 "guohan")。
- other.name:被比较对象的 name 属性(比如 obj2.name 是 "gh")。
- ==:判断两者的 name 是否相同。
- return:将判断结果(True 或 False)返回给 == 运算符
复制代码 __iter__: 让对象成为迭代器- class Foo:
- def __iter__(self):
- yield 1
- yield 2
- yield 3
- obj = Foo()
- for i in obj:
- print(i)
- >>>
- 1
- 2
- 3
复制代码
让你自己写的类,能用和列表、字典一样的 “键 / 索引操作”(比如 obj[key]),不用额外记新方法,还能按需求自定义规则:
__setitem__:
__getitem__:
__delitem__:
- #1
- class Foo(object):
- def __init__(self):
- self.dict = {}
- def __setitem__(self, key, value):
- self.dict[key] = value
- def __getitem__(self,key):
- return self.dict[key]
- def __delitem__(self,key):
- del self.dict[key]
- def __call__(self):
- return self.dict
- obj = Foo()
- obj['k1'] = 123 # 内部会自动调用 __setitem__方法
- obj['k2'] = 666
- print(obj(),type(obj())) >>>{'k1': 123, 'k2': 666} <class 'dict'>
- print(obj['k1'])
- print(obj['k2'])
- del obj['k2']
- print(obj(),type(obj()))
- #2
- class Foo(object):
- def __init__(self):
- self.dict = {}
- def __setitem__(self, key, value):
- self.dict[key] = value
- def __getitem__(self,key):
- return self.dict[key]
- def __delitem__(self,key):
- del self.dict[key]
- def __str__(self):
- return f'{self.dict}'
- obj = Foo()
- obj['k1'] = 123 # 内部会自动调用 __setitem__方法
- obj['k2'] = 666
- print(obj,type(obj)) >>>{'k1': 123, 'k2': 666} <class '__main__.Foo'>
- print(obj['k1'])
- print(obj['k2'])
- del obj['k2']
- print(obj,type(obj))
复制代码
上下文管理: __enter__(self) __exit__(self,exc_type,exc_val,exc_tb)
- class Foo(object):
- def __enter__(self):
- print('开始')
- return 333
- def __exit__(self,exc_type,exc_val,exc_tb):
- print('结束')
- #上下文管理语句
- with Foo() as f: #先执行enter方法将其返回值给f再执行上下文管理语句中的内容最后去执行exit方法
- print(f)
- >>>
- 开始
- 333
- 结束
复制代码
3.内置函数补充
1.isinstance,判断是不是类的实例 返回布尔类型- class Foo:
- def __init__(self):
- pass
- obj = Foo()
- print(isinstance(obj,Foo))
复制代码
2.issubclass,判断是否为某个类的派生类 返回布尔类型- class Foo:
- def __init__(self):
- pass
- class Base(Foo):
- pass
- class Bar(Base):
- pass
- print(issubclass(Bar,Foo))
复制代码
3.super(),往上一级- class Foo():
- def func(self):
- return 'guohan'
- class Base(Foo):
- pass
- class Bar(Base):
- def __str__(self):
- return f'{super().func()}'
- obj = Bar()
- print(obj)
- #super().func() 根据类的继承关系,按照顺序挨个找func方法并执行(找到第一个就不在找了)
复制代码
4.异常处理
1.基本格式:- try:
- pass
- except Exception as e:
- print(e)
复制代码 2.主动触发异常: raise Exception ( ' 异常原因‘ )- def run():
- try:
- num = input('输入数字:')
- if not num.isdecimal():
- raise Exception('输入的不是数字')#主动触发异常,将异常信息再最后面显示
- else:
- print(int(num))
- except Exception as e:
- print(f'异常原因:{str(e)}')
- if __name__ == '__main__':
- run()
-
- >>>输入数字:g
- >>>异常原因:输入的不是数字
复制代码
3.finally
自定义异常\抛出异常:待补(写项目时)
19-8 异常:自定义和抛出异常_哔哩哔哩_bilibili
5.迭代器,生成器,可迭代对象
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |