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

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

四、對象的描述器

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

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

在面向?qū)ο缶幊虝r(shí),如果一個類的屬性有相互依賴的關(guān)系時(shí),使用描述器來編寫代碼可以很巧妙的組織邏輯。在 Django 的 ORM 中,models.Model中的 InterField 等字段, 就是通過描述器來實(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

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

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

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

#!/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

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

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

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