描述符
import numbers
class IntgerField:
def __get__(self, isinstance, owner):
print('获取age')
return self.num def __set__(self, instance, value):
print('设置age值时')
if not isinstance(value, numbers.Integral):
raise ValueError('int need')
self.num = value
def __delete__(self, instance):
pass class User:
age = IntgerField() // 数据属性描述符,查找优先级最高 user = User()
user.age = 33
print(user.age)



上述的User可以看做数据库中的表,假设我们要控制user中age的赋值类型,固然可以使用以下形式进行拦截:

class User:
age = 33
def __setattr__(self, name, value):
pass // 这里进行类型检测
又或者:
class User:
@property
def age(self):
return self._num
@age.setter
def age(self,value):
self._num = value // 这里进行类型检测

但是这种一两次还行,多了就是在写重复代码,所以就可用上述类IntgerField中定义__get__,__set__等实现属性描述符的方式进行拦截。

getattributegetattrsetattr、__delattr__等方法用来实现属性查找、设置、删除的一般逻辑,而对属性的控制行为就由属性对象来控制。这里单独抽离出来一个属性对象,在属性对象中定义这个属性的查找、设置、删除行为。这个属性对象就是描述符。

描述符对象一般是作为其他类对象的属性而存在。在其内部定义了三个方法用来实现属性对象的查找、设置、删除行为。这三个方法分别是:

get(self, instance, owner):定义当试图取出描述符的值时的行为。

set(self, instance, value):定义当描述符的值改变时的行为。

delete(self, instance):定义当描述符的值被删除时的行为。

其中:instance为把描述符对象作为属性的对象实例;

owner为instance的类对象。

描述符有数据描述符和非数据描述符之分

只要至少实现__get__、set、__delete__方法中的一个就可以认为是描述符;

只实现__get__方法的对象是非数据描述符,意味着在初始化之后它们只能被读取;

同时实现__get__和__set__的对象是数据描述符,意味着这种属性是可读写的。

属性查找规则

当查找对象上的某个属性时,假设是user.age,顺序先是判断该实例所指向的类以及基类的__dict__中查找,并且如果该属性数据属性描述符,就会调用描述符中的__get__方法

如果该age直接出现在obj.__dict__上,直接返回obj.dict['age']

如果该属性出现在User中或基类中,且该属性是非数据属性描述符,就会调用其__get__方法,如果不是非数据属性描述符,就会调用User或基类的User或基类.dict['age']

如果这些都没有,且User上也没有__getattr__方法,就会报错

python之属性描述符与属性查找规则的更多相关文章

  1. Python 属性描述符和属性的查找过程

    属性描述符可以用来控制给属性赋值的时候的一些行为 import numbers class IntField: def __get__(self, instance, owner): return s ...

  2. Python:高级主题之(属性取值和赋值过程、属性描述符、装饰器)

    Python:高级主题之(属性取值和赋值过程.属性描述符.装饰器) 背景 学习了Javascript才知道原来属性的取值和赋值操作访问的“位置”可能不同.还有词法作用域这个东西,这也是我学习任何一门语 ...

  3. Python属性描述符

    实现了__get__.set.__delete__中任意一个方法的类,称之为属性描述符. 属性描述符可以控制属性操作时的一些行为. 只要具有__get__方法的类就是描述符类. 如果一个类中具有__g ...

  4. Object.defineProperty 与 属性描述符

    为JavaScript对象新增或者修改属性,有两种不同方式:直接使用=赋值或者使用Object.defineProperty 定义,使用后者的话还可以设置属性的描述符. Object.definePr ...

  5. JavaScript.descriptor(属性描述符)

    属性描述符是对JavaScript属性的描述,包括:value.writable.enumerable.configurable,除value其他默认为true. 本文包括: 取得属性描述符. Obj ...

  6. python描述符和属性查找

    python描述符 定义 一般说来,描述符是一种访问对象属性时候的绑定行为,如果这个对象属性定义了__get__(),__set__(), and __delete__()一种或者几种,那么就称之为描 ...

  7. python高级编程之最佳实践,描述符与属性01

    # -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #最佳实践 """ 为了避免前面所有的 ...

  8. python 属性描述符

    import numbers class IntField: # 一个类只要实现了这个魔法函数,那么它就是属性描述符 #数据描述符 def __get__(self, instance, owner) ...

  9. 深入理解javascript对象系列第三篇——神秘的属性描述符

    × 目录 [1]类型 [2]方法 [3]详述[4]状态 前面的话 对于操作系统中的文件,我们可以驾轻就熟将其设置为只读.隐藏.系统文件或普通文件.于对象来说,属性描述符提供类似的功能,用来描述对象的值 ...

随机推荐

  1. vue之v-for循环的使用

  2. python购物车作业

    # -*- coding:utf8 -*- # Author:Wang Yao goods = [{"name": "电脑", "price" ...

  3. mongodb 系列 ~ mongo的两种引擎介绍对比

    一 简介 两种引擎方式的对比二  对比与说明   1 版本支持      MMAP引擎 3.2版本之前,默认引擎       WT 引擎 3.2版本之后,默认引擎   2 并发性能(核心)     M ...

  4. 项目:《JavaWeb图书管理系统视频》--代码修复还可以运行起来

    1. 系统设计--项目效果图请看最后面 1技术选型 (系统架构) JSTL + JSP + Servlet + JavaBean + BeanUtils + FileUpload + JavaMail ...

  5. java String、StringBuffer、StringBuild、StringTokenizer

    StringBuffer线程安全.StringBuilder线程不安全 效率: StringBuilder(线程不安全) > StringBuffer(线程安全) > String Str ...

  6. hadoop概念

    hadoop What is Apache Hadoop? The Apache Hadoop  project develops open-source software  for reliable ...

  7. 集合排序 Comparator和Comparable的使用区别

    Java 排序 Compare  Comparator接口 Comparable接口 区别 在Java中使用集合来存储数据时非常常见的,集合排序功能也是常用功能之一.下面看一下如何进行集合排序,常用的 ...

  8. Python运维开发基础06-语法基础【转】

    上节作业回顾 (讲解+温习120分钟) #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen # 添加商家入口和用户入口并实现物 ...

  9. javascript面向对象学习

    1.this指向问题,指向的是当前的方法属于谁,当前的方法属于谁就指向谁!! 例子: oDiv.onclick = function () { this指向的是oDiv,因为这个方法属于oDiv } ...

  10. Linux目录结构以及文件操作

    Linux目录结构 UNIX 是以目录为主的,Linux 也继承了这一优良特性. Linux 是以树形目录结构的形式来构建整个系统的,可以理解为树形目录是一个用户可操作系统的骨架.虽然本质上无论是目录 ...