如何正确使用@property

本篇内容主要讲解“如何正确使用@property”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何正确使用@property”吧!

创新互联建站坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站建设、成都做网站、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的银海网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!

他们是这样说的:

class People:     def __init__(self, name):         self.name = name         self._work = '还没有找到工作'      @property     def work(self):         return self._work      @work.setter     def work(self, value):         self._work = value

运行效果如下图所示:

如何正确使用@property

但实际上,这段代码里面,@property装饰器根本没有任何存在的必要,代码完全可以进一步简化:

class People:     def __init__(self, name):         self.name = name         self.work = '还没有找到工作'

运行结果完全一样:

如何正确使用@property

那么,使用@property装饰器的意义在哪里呢?

的确,在上面的例子里,@property装饰器没有任何存在的必要,因为这里读取一个对象的属性,仅仅是“返回数据”而已。但有些情况下,不仅仅要读取,还要计算。

我举一个例子,不知道你有没有这样的经历,你刚刚看了一眼手机,发现现在时间是23:10分。30秒以后,你朋友碰巧问你多少点了,你立刻回答:23:10分。他一看手表,还真是。于是惊呼,你怎么不看表就知道时间?

例如我们现在要实现一个ProxyProvider类,它读取 redis,获取最新的代理 IP,然后随机返回一条。另外有一个程序,会增加新的代理 IP 到  Redis 中。但频率不高。

所以,ProxyProvider这个类,不需要每次获取 IP  的时候都读取数据库,每小时读取一次就可以了。如果不用@property装饰器,你可能会这样写代码:

import time import random   class ProxyProvider:     def __init__(self):         self.pool = []         self.last_update_time = 0      def get_proxy(self):         now = time.time()         if now - self.last_update_time > 3600 or not self.pool:             selfself.pool = self.get_all_proxies_from_redis()         return random.choice(self.pool)

如果你经常看 Java 代码,你会发现大量的这种get_xxx、set_xxx的写法。

于是,调用的时候,要这样调用:

provider = ProxyProvider() provider.get_proxy()

如果用@property,那么代码可以改写为:

import time import random   class ProxyProvider:     def __init__(self):         self.pool = []         self.last_update_time = 0      @property     def proxy(self):         now = time.time()         if now - self.last_update_time > 3600 or not self.pool:             selfself.pool = self.get_all_proxies_from_redis()         return random.choice(self.pool)

于是读取的时候,这样写:

provider = ProxyProvider() provider.proxy  # 注意这里不加括号

我们可以看到,整体代码逻辑是一样的,代码里并没有精简。不过在调用的时候,前者是调用一个方法,后者是读取一个属性。

同理,如果要修改数据,不使用@property的时候,需要实现一个set_xxx方法。但是使用了@property装饰一个方法,也可以在设置数据的时候实现一些内部逻辑,例如:

import time import random   class ProxyProvider:     def __init__(self):         self.pool = []         self.special_ip = set()         self.last_update_time = 0      @property     def proxy(self):         now = time.time()         if now - self.last_update_time > 3600 or not self.pool:             selfself.pool = self.get_all_proxies_from_redis()         return random.choice(self.pool + list(self.special))      @proxy.setter     def proxy(self, value):         if not value.startswith('http'):             proxy = f'http://{ip}'         if proxy in self.special_ip:             return         self.special_ip.add(proxy)

而对于调用者来说,这些复杂的检查逻辑都是透明的:

provider = ProxyProvider() provider.proxy = '123.45.67.89'

对于习惯于 Java 的人来说,他们可能喜欢显式写出get_xxx和set_xxx方法。但是对于习惯 Python  的人来说,我觉得使用@property会让代码的可读性更好。

到此,相信大家对“如何正确使用@property”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!


分享文章:如何正确使用@property
文章起源:http://scyanting.com/article/igoohs.html