欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Python中用Descriptor實現類級屬性(Property)詳解

系統 2310 0

上篇文章簡單介紹了python中描述器(Descriptor)的概念和使用,有心的同學估計已經Get√了該技能。本篇文章通過一個Descriptor的使用場景再次給出一個案例,讓不了解情況的同學可以更容易理解。

先說說decorator

這兩個單詞確實是有些相似,同時在使用中也是形影不離。這也給人造成了理解上的困難,說裝飾器和描述器到底是怎么回事,為什么非得用一個@符號再加上描述器才行。

很多文章也都把這倆結合著講,我自己看完之后都會覺得很繞。其實學習一個知識點,和做項目開發一個功能是一樣的。在功能拆分的時候我們都會盡量的把任務拆分的足夠小,然后才分配到開發者頭上。這樣保證各個任務的獨立性,完整性,并且易于做進度管理。在任務開發的時候也不能把你的任務都放到一個函數/接口中去做,以避免各功能間產生高耦合的狀況,導致后期難以維護。

再說回到學習一個技術點,如果你總是嘗試一下子就要掌握兩個或多個技術點,結果可能是忙活了半天,發現還是暈頭轉向。

擦,好像扯遠了。

說Descriptor是Descriptor, Decorator是Decorator,遇到不懂的地方,各個擊破,哪里不懂點哪里。所以先說Decorator, 關鍵點是你要意識到這就是一個語法糖 。所謂語法糖就是讓你可以用簡單的方式寫代碼。本質上裝飾器(Decorator)就是這樣:

復制代碼 代碼如下:

def decorator(func):
??? def wrapper():
??????? print 'in decorator'
??????? func()
??? return wrapper

def func():
??? print 'in func'

# 把func裝飾一下
func = decorator(func)? # 左邊的func其實是那個wrapper, 你執行它的時候會,它會幫你執行func()
# 等同于你在定義func的時候加上@
@decorator
def func():
??? print 'in func'

正題:通過Descriptor來做一個類級的Property

常見的Property是這樣的:

復制代碼 代碼如下:

class Foo(object):
??? _name = 'the5fire'

??? @property
??? def name(self):
??????? return self._name

這中property的使用,是實例級的應用。因為只有在 foo = Foo() 之后,才可以 foo.name 。

但是如果我需要一個類級的屬性應該怎么做呢,就像是 classmethod一樣,不需要實例化類我就可以調用。對應的需求是這樣的,定義了一個基類DBManage:

復制代碼 代碼如下:

class DBManage(object):
??? @classmethod
??? def table_name(cls):
??????? return cls.__name__.lower()

??? @classmethod
??? def select_all(cls):
??????? sql = "SELECT * FROM %s""" % cls.table_name()
??????? # 執行這個語句的代碼
??????? return result

這其實一個對應著數據庫中某張表的基礎模型,我希望其他的Model都來繼承它,然后可以重用這個table_name的方法(目前還是方法)。

我只需要這么定義User模型即可:

復制代碼 代碼如下:

class User(DBManage):
??? pass

然后這么定義Post模型:
復制代碼 代碼如下:

class Post(DBManage):
??? pass

這樣我如果需要查所有的User數據,只需要 User.select_all() 即可,同理Post也是如此 Post.select_all() 。但此時發現一個有點不爽的事情。那就是基類中的 cls.table_name() 這個代碼,table_name看起來就是屬性,卻需要用調用方法的方式獲取。不妥。

于是自定義了一個classproperty:

復制代碼 代碼如下:

class classproperty(object):
??? def __init__(self, func):
??????? self.func = func

??? def __get__(self, instance, klass):
??????? return self.func(klass)

這需要這樣,我在DBManage中的代碼就可以改為:

復制代碼 代碼如下:

class DBManage(object):
??? @classproperty
??? def table_name(cls):
??????? return cls.__name__.lower()

??? @classmethod
??? def select_all(cls):
??????? sql = "SELECT * FROM %s""" % cls.table_name? # 多么直觀


這就是Descriptor另外的一個使用案例了。
可能有人或有一個小疑問:為毛你不是在sql賦值時直接 sql = "SELECT * FROM %s" % cls.__name__.lower() 。這個問題,問的非常好,原因就一個字:懶。懶得以后每次都得敲那么多代碼。


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲国产清纯 | 业余护士毛茸茸 | 夜夜骚 | 一级免费黄色免费片 | 欧美精品国产第一区二区 | 青草青草久热精品视频在线网站 | 波多野结衣日韩 | 日韩亚洲欧美中文高清在线 | 色免费在线 | 日韩www| 国产日韩一区二区三区 | 亚洲自偷自偷精品 | 亚洲精品久久婷婷丁香51 | 奇米777在线观看 | 91精品久久久久久久久网影视 | 国产精彩视频在线 | 欧美一级二级三级 | 欧美日韩在线看 | 久久99深爱久久99精品 | 日本中文字幕在线视频 | 国产成人91高清精品免费 | 国产精品久久久久秋霞影视 | 亚洲欧美国产日本 | 一级淫片免费 | 日韩欧美一区二区三区四区 | 日本免费一级视频 | 久久99热只有视精品6国产 | 午夜影视免费片在线观看 | 日韩av线 | 亚洲偷图色综合色就色 | 国产一区在线免费观看 | 亚洲网视频 | 欧美日视频 | 激情五月色婷婷 | 狠狠色噜噜狠狠狠狠97影音先锋 | 欧美一a一片一级一片 | 日本在线黄 | 国产一级大片 | 99视频在线观看精品 | 国产亚洲精品久久久999无毒 | 久久精品亚洲成在人线av网址 |