大家好,欢迎来到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