python 描述符

python 描述符你们单位在国外搞了个服务器,立足于美利坚,受美国法律保护。用来存放你懂的资源,以图片和电影为主。最近流量非常可观,为了更好的服务客户,改善用户体验。你们老板决定增加一个投票区,用户可以给自己喜爱的作品投票,每个月评出最喜爱作品,并且从用户中挑选3名用户作为获奖用户,奖品为苍老师签名写真集。这还不简

大家好,欢迎来到IT知识分享网。

    你们单位在国外搞了个服务器,立足于美利坚,受美国法律保护。用来存放你懂的资源,以图片和电影为主。最近流量非常可观,为了更好的服务客户,改善用户体验。

  你们老板决定增加一个投票区,用户可以给自己喜爱的作品投票,每个月评出最喜爱作品,并且从用户中挑选3名用户作为获奖用户,奖品为苍老师签名写真集。这还不简单

  不就是一个投票嘛,先写一个类,咔咔你就写完了,代码是这样的。

class MovieVoted(object):
	def __init__(self, title, score, actor):
		self.title = title
		self.score = score
		self.actor = actor

	def voted(self, value):
		return {'title':self.title,'score':self.score,'actor':self.actor}

    很快你把代码完善以后就上线,对自己的结果很满意。想必老板也会给升职加薪,到时候迎娶前台妹子过上人生巅峰。正当陶醉在美梦的时候,突然听到老板在办公室骂骂咧咧:哪个傻X做的。

  这时候你感觉不对,立马上到你们的网站,看到你们的评选域出现了很多负分,电影评分是负分怎么行呢。原来是隔壁老李和你们家干的是一样的业务,发现你们有这个功能以后就到你们把电

  影评分都评为负的,给用户带来了不好的体验。老板骂了你一顿后,并且告诉你今天不把这个事情解决明天就不用来了。

 

    面对需求毫无头绪,难道人生就是这么残酷么。你立马想到去年在东莞时认识的程序员老王,老王毕竟是大厂工程师,见过大世面,想必很多奇淫技巧不在话下。于是你就给老王打电话

  老王好像不方便,听那声音好像在跑步。5分钟后老王给你回了电话,你跟他说说具体情况,不一会儿老王把你的代码给改了改,给你发了回来。

class Attr(object):
	def __init__(self, name, type_):
		self.name = name
		self.type_ = type_

	def __get__(self, instance, owner):
		return instance.__dict__[self.name]

	def __delete__(self, instance):
		del instance.__dict__[self.name]

	def __set__(self, instance, value):
		if not isinstance(value, self.type_):
			raise TypeError('expected an %s' % self.type_)
		if self.name == 'score' and value < 0:
			raise ValueError('score can not be negative')
		instance.__dict__[self.name] = value


class MovieVoted(object):
	score = Attr('score', int)
	title = Attr('title', str)
	actor = Attr('actor', str)

	def voted(self, value):
		return {'title': self.title, 'score': self.score, 'actor': self.actor}


m1 = MovieVoted()
m1.title = 'xxx'
m1.actor = '苍井空'
m1.score = 10
#m1.score = -10          #这时候会报错

    不愧是见过世面的人,一下子就写出来。不过有很多东西你都没见过,这时候老王给你耐心解释。你原来的程序不行是因为你定义的类,对于实例的变量是没有任何限制的,可以赋值为

  任意类型,也可以赋值为任意大小。分数可以赋值为str类型的,当然也可以赋值为负数。现在你需要做的是对实例变量赋值的时候加上一定的条件。python在这方面提供了一个很好的功能

  即描述符。你看到函数中出现的__get__、__set__、__delete__就是描述符函数。下面分别给你解释一下。

 

1def __get__(self, instance, owner):

这个函数将会在查询值的时候被触发,即print(m1.title) 的时候。instance,owner是它自动会接收的两个参数,instance即m1这个实例,owner即instance所属的类,即MovieVoted.这个函数被触发
通过实例内置方法__dict__[self.name]的方法将值查询到,并且返回。

2.def __set__(self, instance, value):
这个函数将会在设定值的时候被触发,instance代表着当前实例,即m1,value代表着设定的值即’苍井空’。首先判断value的值是否属于预先设定的类型,即self.type_这里预先设定的是 str类型。如果不属于

就会触发TypeError,这里加了一层限制,title的值只能为字符串,有点像静态语言,事先将一个变量的类型固定下来。如果类型没有问题,再判断是不是’score’,如果是,并且数字小于0,即触发一个ValueError.

3.def __delete__(self, instance):
这个和__get__很像,在删除属性的时候被触发,比如del m1.title的时候就会触发。

这里面有一个需要注意的地方是,实例一开始并没有初始化变量。而统一用的都是类里面的变量,千万不要把类变量放到初始化函数里面哦。放进去虽然能正常运行,但是就起不到描述符的作用了。

不愧是见过世面的人,你对老王的崇拜之情又进一步加强了,并且约好了下一再一起去东莞。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/30634.html

(0)
上一篇 2023-11-02 20:00
下一篇 2023-11-07 09:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信