05 方法相关补充
1. 私有化方法:
- 也是方法名前面加两个下划线
2. 内置特殊方法:
-
生命周期方法详见另一笔记
-
其他内置方法:
1. 信息格式化操作
- [__str__]
def __str__(self): return 撰写语句展现实例的属性信息 # 此时输出的就是上述方法设定的语句 print(实例)
- [__repr__],可以实现和上述方法一样的方法,但是当上述方法已经存在时,打印实例默认调用上述方式,这个方法主要面向开发人员使用
#但是可以利用专门调用的方式来调用这个方法 print(repr(实例)) #可以在交互模式下,直接输入实例就默认调用此方法,如: >>>实例名
2. 调用操作:[__call__]
—— 让一个实例对象可以直接调用
def __call__(self,*args,**kwargs): pass #实例对象 p = 类名() p() #这样就可以调用上述方法 #传入参数,未指明的存在元组中,指明的存在字典中 p(123,243, name = "sz")
应用场景1: 更方便的指定和传入参数
class PenFactory: def __init__(self, p_type): self.p_type = p_type def __call__(self, p_color): print("创建了一个%s这个类型的画笔, 它是%s颜色" % (self.p_type, p_color)) gangbiF = PenFactory("钢笔") gangbiF("红色") gangbiF("绿色") gangbiF("黄色")
3.索引操作
- 增改:[__setitem__]
- 查:[__getitem__]
- 删:[__delitem__]
class Person: def __init__(self): self.cache = {} def __setitem__(self, key, value): # print("setitem", key, value) self.cache[key] = value def __getitem__(self, item): # print("getitem", item) return self.cache[item] def __delitem__(self, key): # print("delitem", key) del self.cache[key] p = Person() p["name"] = "sz" print(p["name"]) del p["name"] # print(p["name"]) print(p.cache)
4.切片操作
对一个实例对象进行切片操作,统一由“索引操作”中的几个方法进行管理
简单示例
class Person: def __init__(self): self.items = [1, 2, 3, 4, 5, 6, 8] #自定义的切片操作, #key应该是slice类型 #有默认的start,end,step属性,所以方便赋值 def __setitem__(self, key, value): if isinstance(key, slice): self.items[key] = value def __getitem__(self, item): print("getitem", item) def __delitem__(self, key): print("delitem", key) p = Person() p[0: 4: 2] = ["a", "b"] print(p.items)
5. 比较操作
可以自定义对象“比较大小,相等以及真假”规则
- [__eq__] —— 内置的类比较规则重写方法,当自定义类进行比较时,自动调用这个方法。这个方法主要用于匹配
相等时
的返回 - [__ne__] —— 内置的类比较时,如果
不相等
调用的方法,如果没有重写,不相等时默认调用上述方法 - [__gt__] —— 大于
- [__ge__] —— 大于等于
- [__lt__] —— 小于
- [__le__] —— 小于等于
- [__bool__] —— 确定类实例的布尔值
注意:
- 如果对于反向操作的比较复杂,只定义了其中一个方法,但使用的是另一种比较运算,那么解释器会采用调换参数的方式进行调用该方法;
- 但是,默认不会采用叠加操作,比方说,如果你只定义了
相等
和小于
两个方法,想要两个类实例比较小于等于
,就会报错 - 针对第二点,可以调用
functools
模块,在类上面加上@functools.total_ordering
装饰器,将会自动补全其余比较方法,以完成期望的比较效果
6.遍历操作
- 使用for in 遍历:
- 利用 实现__getitem__方法
#当已定义__getitem__方法后,注意设定终止条件 for i in 实例: #这里的 i 就是自动调用的__getitem__方法 print(i)
- 利用 实现__iter__和__next__方法
注意:iter()方法,可以传入一个可调用对象,当想用自定义的实例作为参数传入时,需要对该类重写__call__()方法# 撰写__iter__方法,构造一个迭代器 # 然后利用__next__方法,访问迭代元素 # 如下所示,已经略去类框架 def __iter__(self): self.result = 1 return self def __next__(self): self.result += 1 if self.result >= 6: raise StopIteration("停止遍历") return self.result p = Person() for i in p: print(i)
7.描述器
可以描述一个属性操作的对象
- 利用
property()
类,亦可以用上文的@property装饰器
#以下操作在类的定义里写,这样调用实例的属性时就可以直接操作了 属性名 = property(查找方法,增改方法,删除方法)
- 自行实现
__get__()
、__set__()
、__delete__()
方法
注:- 资料描述器,实现了get,set
- 非资料描述其,只实现了get
- 属性调用优先级:
资料描述器 > 实例属性 > 非资料描述器