解答三個問題,描述是什麼?如何實現?使用場景?
一、什麼是描述符
描述符就是一個具有繫結行為的物件屬性,其屬性訪問將由描述符協議中的方法覆蓋。這些方法為 __get__
、__set__
和 __delete__
。如果這些方法中的任何一個針對某個物件定義,那麼它就被認為是一個描述符。
__get__
用於訪問屬性。它返回屬性的值,或者在所請求的屬性不存在的情況下出現 AttributeError
異常
__set__
將在屬性分配操作中呼叫。不會返回任何內容
__delete__
控制刪除操作。不會返回內容
二、描述符的實現方式
2.1 基於類建立
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = `liao gao xiang`
class Descriptor(object):
""""""
def __init__(self):
self._name = ``
def __get__(self, instance, owner):
print("__get__")
return self._name
def __set__(self, instance, value):
print("__set__")
self._name = value
def __delete__(self, instance):
print("__delete__")
del self._name
class Person(object):
name = Descriptor()
p = Person()
print(p.name)
p.name = `liao gao xiang`
del p.name
# print(p.name)
2.2 使用propety()函式
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = `liao gao xiang`
class Person(object):
def __init__(self):
self._name = ``
def fget(self):
print("Getting: %s" % self._name)
return self._name
def fset(self, value):
print("Setting: %s" % value)
self._name = value.title()
def fdel(self):
print("Deleting: %s" % self._name)
del self._name
name = property(fget, fset, fdel, "I`m the property.")
p = Person()
print(p.name)
p.name = `liao gao xiang`
del p.name
# print(p.name)
2.3 使用@property裝飾器
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = `liao gao xiang`
class Person(object):
""""""
def __init__(self, name):
self._name = name
@property
def name(self):
print("get_name")
return self._name
@name.setter
def name(self, value):
print("set_name")
self._name = value
@name.deleter
def name(self):
print("del_name")
del self._name
p = Person()
print(p.name)
p.name = `liao gao xiang`
del p.name
# print(p.name)
三、描述符的使用場景
- 通過結合使用描述符,可以實現優雅的程式設計,允許建立 Setters 和 Getters 以及只讀屬性
- 根據值或型別請求進行屬性驗證
- 大量用於各種框架中,比如Django的models