最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

實(shí)現(xiàn)python?namedtuple元類編程

 更新時(shí)間:2023年07月25日 16:56:26   作者:weapon  
這篇文章主要為大家介紹了實(shí)現(xiàn)python?namedtuple元類編程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

起步

namedtuple 是 collections 模塊下的一個(gè)功能,它是類工廠函數(shù),能返回 tuple 子類,允許通過字段名向元組中取值,性能上接近于元組。

Person = namedtuple('Person', 'name age')
p = Person(name='Tony', age=18)
print(p.name)  # 'Tony'
print(p.age)   # 18

我們來試著自己動(dòng)手來實(shí)現(xiàn)這個(gè) namedtuple 功能。因?yàn)檫@個(gè)功能需求明確,沒什么模塊依賴,通過自己的實(shí)現(xiàn)后再去看看真正在 cpython 里的源碼就會(huì)比較清晰。

需求分析

對于代碼 Person = namedtuple('Person', 'name age') 讓它等價(jià)于:

class Person(tuple):
    def __new__(cls, name, age):
        return tuple.__new__(cls, (name, age))
    @property
    def name(self):
        return self[0]
    @property
    def age(self):
        return self[1]

那么有一種實(shí)現(xiàn)就是,拼湊成這樣的代碼塊字符串,再通過 exec(code) 來創(chuàng)建類,舊版本(小于 3.7)的 namedtuple 在 cpython 中還真就是這么實(shí)現(xiàn)的。

PS: 重寫了 __new__ 而不是 __init__ ,有一個(gè)原因是因?yàn)樵M一旦創(chuàng)建就不可變。為了能夠通過字段名取值,這里引入了 property 修飾符。

構(gòu)造類的字符串模板創(chuàng)建類

基于這個(gè)思路一個(gè)簡陋的就能寫了出來:

# 類名稱模板
_class_template = '''
class {typename}(tuple):
    def __new__(_cls, {arg_list}):
        return tuple.__new__(_cls, ({arg_list}))
{field_defs}
'''
# 屬性模板
_field_template = '''
    @property
    def {name}(self):
        return self[{index}]
'''
def namedtuple(typename, field_names):
    field_names = field_names.split()
    class_definition = _class_template.format(
        typename=typename,
        arg_list=arg_list = repr(field_names).replace("'", "")[1:-1],
        field_defs=''.join(_field_template.format(index=index, name=name)
                               for index, name in enumerate(field_names))
    )
    namespace = {}
    exec(class_definition, namespace)
    return namespace[typename]
# use demo
Person = namedtuple('Person', 'name age')
p = Person(name='Tony', age=18)
print(isinstance(p, tuple)) # True
print(p.name)               # Tony
print(p.age)                # 18

cpython 中的 namedtuple 便是基于這個(gè)思路實(shí)現(xiàn)的

源碼:https://github.com/python/cpy...,這個(gè)實(shí)現(xiàn)方式一直沿用到了 3.6.x 。

直到因?yàn)樾阅茉蚨M(jìn)行了改版,PR見:https://github.com/python/cpy...

基于元類編程

改進(jìn)后的 namedtuple 更能體現(xiàn)元類編程的思想,對性能也有明顯的改善。我用簡化的代碼來展示改版后的 namedtuple 的工作內(nèi)容:

def _tuplegetter(index):
    @property
    def _getter(self):
        return self[index]
    return _getter

def namedtuple(typename, field_names):
    field_names = field_names.split()
    arg_list = repr(field_names).replace("'", "")[1:-1]
    s = f'def __new__(_cls, {arg_list}): return tuple.__new__(_cls, ({arg_list}))'
    namespace = {}
    exec(s, namespace)
    __new__ = namespace['__new__']
    class_namespace = {'__new__': __new__}
    for index, name in enumerate(field_names):
        class_namespace[name] = _tuplegetter(index)
    result = type(typename, (tuple,), class_namespace)
    return result

到此,一個(gè)簡易版的 namedtuple 就結(jié)構(gòu)就完成了,改進(jìn)后的 exec 調(diào)用中只有一行代碼,性能會(huì)更好,舊版本的還會(huì)額外 import 其他依賴。然后就是構(gòu)造元類編程中類屬性和方法了。屬性的獲取是通過寫的 _getter 來完成,而實(shí)際上源碼上會(huì)委托給 operator.itemgetter 函數(shù)。

總結(jié)

相信從本文中理解了 namedtuple 的設(shè)計(jì)和實(shí)現(xiàn)原理,再去閱讀源代碼,能更快的理解源碼,起到事半功倍的效果。

以上就是實(shí)現(xiàn)python namedtuple元類編程的詳細(xì)內(nèi)容,更多關(guān)于python namedtuple元類的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

古田县| 海淀区| 东兰县| 沂源县| 武定县| 手机| 眉山市| 河源市| 巴彦淖尔市| 双江| 秀山| 墨竹工卡县| 彩票| 武穴市| 桂平市| 金溪县| 华亭县| 大竹县| 西丰县| 泗水县| 涞源县| 建德市| 义乌市| 荥阳市| 平山县| 根河市| 邹城市| 韶关市| 水富县| 沐川县| 株洲市| 阜康市| 洛川县| 桃江县| 长乐市| 顺义区| 安岳县| 高唐县| 潞城市| 上思县| 新蔡县|