Python 代偿 类和对象

本文介绍了Python中的几个重要魔法方法,包括__contains__用于`in`和`notin`操作,如果没有实现会寻找__iter__和__next__,或者__getitem__。另外,文章还讲解了__iter__和__next__如何协同工作进行迭代,以及__bool__和__len__在布尔测试中的作用。最后,文章讨论了自定义比较运算方法如__lt__、__gt__、__eq__等,以及未定义__ne__时的默认行为。
摘要由CSDN通过智能技术生成

1. __contains__(self,item)

        对于__contains__(self,item),主要用于实现成员关系的检测,其对应的运算符是in和not in

class C:
	def __init__(self,data):
		self.data = data
	def __contains__(self,item):
		print("检测到 in or not in 操作!")
		return item in self.data            # 检索item是否存在

	
c = C([1,2,3,4,5])                          # 向实例对象中输入一个列表
3 in c                                      # 判断 3 是否 在实例对象c中
# 检测到 in or not in 操作! 
# True

        只是简单的判断item是否包含在self.data中,是就返回true,不是就返回false。

2. 代偿

        所谓代偿,就是换另一种方式来实现未实现的功能。当程序没有找到__contains__()方法的时候,会去寻找__iter__()和__next__()方法,如果__iter__()和__next__()方法也没有找到,会去寻找__getitem__()方法。

class C:
	def __init__(self,data):
		self.data = data
	def __iter__(self):
		print("iter",end='->')
		self.i = 0
		return self                # 返回迭代器
	def __next__(self):
		print("next",end='->')
		if self.i == len(self.data):  # 等到下标值与对应数据长度相等时,结束寻找
			raise StopIteration
		item = self.data[self.i]
		self.i += 1
		return item

	
c = C([1,2,3,4,5])
3 in c
# iter->next->next->next->True
6 in c
# iter->next->next->next->next->next->next->False

        上述例子是将列表里面的数据一个一个的返回,直到找到需要的数据时,结束寻找。

        # iter->next->next->next->True  True是3 in c 的结果,会拿3 和return的item进行比较运算。

3.布尔测试

        __bool__(),对于__bool__()魔法方法,在进行布尔测试的时候会触发

class D:
	def __bool__(self):
		print("boy jiji boy~")
		return True    #默认一直返回Ture

	
d = D()
bool(d)
# boy jiji boy~
# True

        如果找不到__bool__(),Python会去寻找__len__()这个魔法方法。

class D:
	def __init__(self,data):
		self.data = data
	def __len__(self):
		print("len")
		return len(self.data)

	
d = D("Python")
bool(d)
# len
# True

        对于上述代码返回的是Ture而不是具体的字符串长度是因为这时进行的是布尔运算,只是触发了__len__(),所以结果仍然是返回True或者False。

4. 比较运算

跟比较运算相关的魔法方法
__lt__(self,other)<
__le__(self,other)<=
__gt__(self,other)>
__ge__(self,other)

>=

__eq__(self,other)==
__ne__(self,other)!=

 

 

 

 

 

 

 

 

        这些方法主要作用于:人们一般都会认为比较字符串比较的是字符串的长度,而不是比较每个字符串的编码值大小,但事实不是这样,结果是恰恰相反的。

class S(str):
	def __lt__(self,other):
		return len(self)<len(other)
	def __gt__(self,other):
		return len(self)>len(other)
	def __eq__(self,other):
		return len(self)==len(other)

	
s1 = S("Python")
s2 = S("python")
# 下面比较的不是编码值的大小,而是比较的字符串长度
s1<s2
# False
s1>s2
# False
s1==s2
# True
s1!=s2
# True

         不要以为s1 == s2的结果是ture,s1 != s2的结果就是false了,因为我们没有定义__ne__()方法,所以进行的仍然是编码值得比较,从而说明这些魔法方法只有在定义(我们自己定义的)的时候才会起作用。

        像是刚才那样s1!=s2的结果是ture,是因为去访问没有定义的__len__()方法去了,如果我们不想出现这样的情况,可以使用None来修饰。

class S(str):
	def __lt__(self,other):
		return len(self)<len(other)
	def __gt__(self,other):
		return len(self)>len(other)
	def __eq__(self,other):
		return len(self)==len(other)
	__ne__ = None

	
s1 = S("Python")
s2 = S("python")

s1!=s2
'''
Traceback (most recent call last):
  File "<pyshell#65>", line 1, in <module>
    s1!=s2
TypeError: 'NoneType' object is not callable
'''

        这时候再去执行s1!=s2测试,就会出现错误信息。同样的,像之前提到的一些魔法方法也可以用None进行修饰。

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学者山羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值