在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Python/ 四、對(duì)象的描述器
二、Enum 的源碼
前言
一、Python 模塊簡(jiǎn)介
一、List(列表)
五、匿名函數(shù)
三、什么是元類
二、循環(huán)語(yǔ)句
二、模塊的使用
三、第一個(gè) Python 程序
線程與進(jìn)程
Python
三、條件語(yǔ)句和循環(huán)語(yǔ)句綜合實(shí)例
四、對(duì)象的描述器
三、類的屬性
一、迭代
五、迭代器和生成器綜合例子
六、運(yùn)算符相關(guān)的魔術(shù)方法
一、枚舉類的使用
前言
一、簡(jiǎn)明概述
二、Python 的基本數(shù)據(jù)類型
多線程編程
五、作用域
四、包
四、枚舉的比較
四、Python 中的變量
六、類的多態(tài)
一、Python 中類也是對(duì)象
一、Python 的 Magic Method
前言
四、生成器
一、面向?qū)ο蟮母拍?/span>
五、類的繼承
二、類
二、使用 <code>type()</code> 動(dòng)態(tài)創(chuàng)建類
進(jìn)程
二、set
三、主模塊和非主模塊
一、字典(Dictionary)
前言
前言
前言
前言
四、集成開(kāi)發(fā)環(huán)境(IDE): PyCharm
前言
四、函數(shù)的參數(shù)
三、lsit 生成式(列表生成式)
四、自定義元類
四、類的方法
二、函數(shù)傳值問(wèn)題
二、注釋
一、條件語(yǔ)句
一、Python 語(yǔ)法的簡(jiǎn)要說(shuō)明
三、函數(shù)返回值
三、基本數(shù)據(jù)類型轉(zhuǎn)換
三、屬性的訪問(wèn)控制
二、Python 的安裝
前言
三、命名規(guī)范
一、Python 自定義函數(shù)的基本步驟
三、自定義類型的枚舉
五、自定義容器(Container)
二、Python 迭代器
前言
二、tuple(元組)
一、Python 簡(jiǎn)介
前言
前言
前言
二、構(gòu)造(<code>__new__</code>)和初始化(<code>__init__</code>)
前言

四、對(duì)象的描述器

一般來(lái)說(shuō),一個(gè)描述器是一個(gè)有“綁定行為”的對(duì)象屬性 (object attribute),它的訪問(wèn)控制被描述器協(xié)議方法重寫(xiě)。這些方法是 __get__(), __set__() , 和 __delete__() 。有這些方法的對(duì)象叫做描述器。

默認(rèn)對(duì)屬性的訪問(wèn)控制是從對(duì)象的字典里面 (__dict__) 中獲取 (get) , 設(shè)置 (set) 和刪除 (delete) 。舉例來(lái)說(shuō), a.x 的查找順序是, a.__dict__['x'] , 然后 type(a).__dict__['x'] , 然后找 type(a) 的父類 ( 不包括元類 (metaclass) ).如果查找到的值是一個(gè)描述器, Python 就會(huì)調(diào)用描述器的方法來(lái)重寫(xiě)默認(rèn)的控制行為。這個(gè)重寫(xiě)發(fā)生在這個(gè)查找環(huán)節(jié)的哪里取決于定義了哪個(gè)描述器方法。注意, 只有在新式類中時(shí)描述器才會(huì)起作用。在之前的篇節(jié)中已經(jīng)提到新式類和舊式類的,有興趣可以查看之前的篇節(jié)來(lái)看看,至于新式類最大的特點(diǎn)就是所有類都繼承自 type 或者 object 的類。

在面向?qū)ο缶幊虝r(shí),如果一個(gè)類的屬性有相互依賴的關(guān)系時(shí),使用描述器來(lái)編寫(xiě)代碼可以很巧妙的組織邏輯。在 Django 的 ORM 中,models.Model中的 InterField 等字段, 就是通過(guò)描述器來(lái)實(shí)現(xiàn)功能的。

我們先看下下面的例子:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

class User(object):
    def __init__(self, name='兩點(diǎn)水', sex='男'):
        self.sex = sex
        self.name = name

    def __get__(self, obj, objtype):
        print('獲取 name 值')
        return self.name

    def __set__(self, obj, val):
        print('設(shè)置 name 值')
        self.name = val

class MyClass(object):
    x = User('兩點(diǎn)水', '男')
    y = 5

if __name__ == '__main__':
    m = MyClass()
    print(m.x)

    print('\n')

    m.x = '三點(diǎn)水'
    print(m.x)

    print('\n')

    print(m.x)

    print('\n')

    print(m.y)

輸出的結(jié)果如下:

獲取 name 值
兩點(diǎn)水

設(shè)置 name 值
獲取 name 值
三點(diǎn)水

獲取 name 值
三點(diǎn)水

5

通過(guò)這個(gè)例子,可以很好的觀察到這 __get__()__set__() 這些方法的調(diào)用。

再看一個(gè)經(jīng)典的例子

我們知道,距離既可以用單位"米"表示,也可以用單位"英尺"表示。 現(xiàn)在我們定義一個(gè)類來(lái)表示距離,它有兩個(gè)屬性: 米和英尺。

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

class Meter(object):
    def __init__(self, value=0.0):
        self.value = float(value)

    def __get__(self, instance, owner):
        return self.value

    def __set__(self, instance, value):
        self.value = float(value)

class Foot(object):
    def __get__(self, instance, owner):
        return instance.meter * 3.2808

    def __set__(self, instance, value):
        instance.meter = float(value) / 3.2808

class Distance(object):
    meter = Meter()
    foot = Foot()

if __name__ == '__main__':
    d = Distance()
    print(d.meter, d.foot)
    d.meter = 1
    print(d.meter, d.foot)
    d.meter = 2
    print(d.meter, d.foot)

輸出的結(jié)果:

0.0 0.0
1.0 3.2808
2.0 6.5616

在上面例子中,在還沒(méi)有對(duì) Distance 的實(shí)例賦值前, 我們認(rèn)為 meter 和 foot 應(yīng)該是各自類的實(shí)例對(duì)象, 但是輸出卻是數(shù)值。這是因?yàn)?__get__ 發(fā)揮了作用.

我們只是修改了 meter ,并且將其賦值成為 int ,但 foot 也修改了。這是 __set__ 發(fā)揮了作用.

描述器對(duì)象 (Meter、Foot) 不能獨(dú)立存在, 它需要被另一個(gè)所有者類 (Distance) 所持有。描述器對(duì)象可以訪問(wèn)到其擁有者實(shí)例的屬性,比如例子中 Foot 的 instance.meter