Python进阶-----自定制property

一、回顾python内置的装饰器@property
  @property的作用就是将类的函数属性同对象的数据属性一样可供对象直接调用(静态属性),而不需要加()

 1 class Room:
 2     def __init__(self,name,width,length):
 3         self.name = name
 4         self.width = width
 5         self.length = length
 6
 7     @property           #这个装饰器可以使得Room实例化的对象直接调用area这个函数属性
 8     def area(self):
 9         return ‘%s 的面积是 %d‘%(self.name,self.length * self.width)
10 r1 = Room(‘卧室‘,10,5)
11 print(r1.area)          #‘卧室 的面积是 50‘
12 print(Room.area)        #类调用静态属性   <property object at 0x000001BEBAF218B8>

二、我们可以通过描述符和类的装饰器来自己制作类似于上述的property
  装饰器也可以是类,描述符主要用到__get__方法,返回的就是需要调用函数的返回值

 1 class diy_property:
 2     def __init__(self,func):
 3         self.func = func
 4     def __get__(self, instance, owner):    #存在__get__所以这个diy_property类就是一个描述符
 5         ‘‘‘类来调用,instance为None,owner为类本身,实例来调用,instance为实例,owner为类本身‘‘‘
 6         if instance == None:
 7             return self                    #仿照property,如果通过类调用静态属性,则返回装饰器的实例对象
 8         res = self.func(instance)          #===> res = r2.area(被修饰类的self) ===> res = r2.area(r2)
 9         return res
10
11 class Room:
12     def __init__(self,name,width,length):
13         self.name = name
14         self.width = width
15         self.length = length
16
17     @diy_property           #==> area=diy_property(area) 相当于定义了一个类属性,即描述符
18     def area(self):
19         return ‘%s 的面积是 %d‘ % (self.name, self.length * self.width)
20
21 r2 = Room(‘客厅‘,15,8)
22 print(r2.area)              #客厅 的面积是 120
23 print(Room.area)            #类调用静态属性 <__main__.diy_property object at 0x000001BEBB0AD1D0>
24 # 通过类的装饰器和描述符基本完成了@property的功能

三、通过自定制property实现延迟计算
  什么是延迟计算:类属性的延迟计算就是将类的属性定义成一个property,只在访问的时候才会计算,而且一旦被访问后,结果将会被缓存起来,不用每次都计算。
  所以解决思路就是:将计算的结果存放至实例的属性字典中,这样再次访问这个静态属性的时候,会直接从实例的属性字典中拿取。避免了重复计算。

 1 class Lazy_property:
 2     def __init__(self,func):
 3         self.func = func
 4     def __get__(self, instance, owner):
 5         print(‘执行我了~~~‘)
 6         if instance == None:            #如果是类本身在调用静态属性时
 7             return self                 #返回装饰器实例对象
 8         else:
 9             res = self.func(instance)
10             setattr(instance,self.func.__name__,res)   #将静态属性的值放入实例的属性字典中,key是静态属性的函数名,value是静态属性的值
11             return res
12
13 class Room:
14     def __init__(self,name,width,length):
15         self.name = name
16         self.width = width
17         self.length = length
18
19     @Lazy_property
20     def area(self):
21         return ‘%s的面积是%d‘%(self.name,self.width*self.length)
22 r3 = Room(‘厨房‘,4,7)
23 print(r3.area)
24 print(r3.__dict__)
25 #>>>执行我了~~~
26 # >>>厨房的面积是28
27 # >>>{‘name‘: ‘厨房‘, ‘width‘: 4, ‘length‘: 7, ‘area‘: ‘厨房的面积是28‘}
28
29 #我们再次调用area这个静态属性
30 print(r3.area)
31 # >>>‘厨房的面积是28‘

  可以发现,再次调用area这个静态属性,程序不会再去调用装饰器描述符中的__get__方法了,因为我们定义的描述符没有__set__方法,所以是一个非数据描述符。所以它的优先级低于实例属性,因为第一次调用area静态属性的时候,描述符就将该属性设置到实例的属性字典中,所以下一次调用
的时候会优先从实例属性字典中查找。

原文地址:https://www.cnblogs.com/Meanwey/p/9902668.html

时间: 2024-11-07 16:47:01

Python进阶-----自定制property的相关文章

Python学习之定制类

本文和大家分享的主要是 python开发中定制类的相关内容,一起来看看吧,希望对大家学习和使用这部分内容有所帮助. 1. python中什么是特殊方法 任何数据类型的实例都有一个特殊方法:  __str__() ·  用于 print 的  __str__ ·  用于 len 的  __len__ ·  用于 cmp 的  __cmp__ ·  特殊方法定义在 class 中 ·  不需要直接调用 · Python 的某些函数或操作符会调用对应的特殊方法 file:///C:\Users\wlc

Python进阶(四十)-数据可视化の使用matplotlib进行绘图

Python进阶(四十)-数据可视化の使用matplotlib进行绘图 前言 ??matplotlib是基于Python语言的开源项目,旨在为Python提供一个数据绘图包.我将在这篇文章中介绍matplotlib API的核心对象,并介绍如何使用这些对象来实现绘图.实际上,matplotlib的对象体系严谨而有趣,为使用者提供了巨大的发挥空间.用户在熟悉了核心对象之后,可以轻易的定制图像.matplotlib的对象体系也是计算机图形学的一个优秀范例.即使你不是Python程序员,你也可以从文中

python进阶九_网络编程(一)

Python网络编程一 一.一些基本概念 在Python网络编程这一节中会涉及到很多网络相关的术语,对于一些最基本的概念,如TCP/IP,Socket等等不再赘述,不明白的可以自己去查一查,对于一些常见但是可能不是很熟悉的术语这里做了一个简要的介绍,后续遇到不会因此止步. SNTP:简单网络时间协议(Simple Network Time  Protocol)简单来说就是用来同步因特网中的计算机时钟,需要注意的是这里的SNTP是用户数据报(UDP)协议. MIME:Multipurpose In

一、Python 进阶 之 函数式编程

Python 进阶 之 函数式编程 写在前面 入门阶段的系列笔记传送门 → 进这里 已经掌握了基础的内容如下: 变量和数据类型:Python 内置的基本类型 List 和 Tuple:顺序的集合类型 条件判断和循环:控制程序流程 Dict 和 Set:根据Key访问的集合类型 函数:定义和调用函数 切片:如何对 list 进行切片 迭代:如何用 for 循环迭代集合类型 列表生成式:如何快速生成列表 接下来我要学会: 函数式编程 如何使用 Python 的模块(内置模块和第三方模块) 面向对象编

python进阶篇

python进阶篇 import 导入模块 sys.path:获取指定模块搜索路径的字符串集合,可以将写好的模块放在得到的某个路径下,就可以在程序中import时正确找到. ? import sys ? sys.path.append("") 重新导入模块 ? reload(模块) ==.is a = [11,22,33] b = [11,22,33] >>>a == b True >>>a is b False >>>a = c

python进阶强化学习

最近学习了慕课的python进阶强化训练,将学习的内容记录到这里,同时也增加了很多相关知识. 主要分为以下九个模块: 基本使用 迭代器和生成器 字符串 文件IO操作 自定义类和类的继承 函数装饰器和类的装饰器 进程和线程 内存管理和垃圾回收机制 基本使用 基本的数据包括:list,tuple(元组),set(集合)和dict(字典).heapq.queue 处理的实际问题是:过滤列表中的负数 解决方案: 列表解析,最好的方式 字典,使用字典的方式和使用列表的方式差不多,都是对value做判断,但

Python 进阶 笔记

慕课网 Python 进阶 http://www.imooc.com/learn/317 笔记 # start: pass # 定义Person类的__init__方法,除了接受 name.gender 和 birth 外,还可接受任意关键字参数,并把他们都作为属性赋值给实例: class Person(object): count = 0 #定义类属性    def __init__(self, name, gender, birth, **kw):        self.name = na

Python环境右键定制

有时候,我们需要将py打包成exe.需要将ui转换成py.需要将py转换成pyc等等,命令行操作起来有点繁琐.所以做了这个教程: 1. py打包成exe 先安装cx_freeze,参照教程:http://www.cnblogs.com/doudongchun/p/3694829.html 建立批处理命令文件py2exe.bat @echo off @cd /d "%~dp0" d:/python32/scripts/cxfreeze %1 --target-dir=d:\py2exe\

有哪些比较好的讲Python进阶的博客?

Python是一种动态解释型的编程语言,它可以在Windows.UNIX.MAC等多种操作系统以及Java..NET开发平台上使用.不过包含的内容很多,加上各种标准库.拓展库,乱花渐欲迷人眼.因此如何进阶Python显得非常重要. 接下来看看比较好的讲Python进阶的博客,我这有十个,希望对你有帮助. 第一个是Planet Python,这是最出名的python博客其中之一: 第二个博客是Eli Bendersky 的博客:Eli Bendersky's website: 第三个博客是Code