欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

起步

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

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

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

需求分析

對(duì)于代碼 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)就是,拼湊成這樣的代碼塊字符串,再通過(guò) exec(code) 來(lái)創(chuàng)建類(lèi),舊版本(小于 3.7)的 namedtuple 在 cpython 中還真就是這么實(shí)現(xiàn)的。

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

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

基于這個(gè)思路一個(gè)簡(jiǎn)陋的就能寫(xiě)了出來(lái):

# 類(lèi)名稱(chēng)模板
_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見(jiàn):https://github.com/python/cpy...

基于元類(lèi)編程

改進(jìn)后的 namedtuple 更能體現(xiàn)元類(lèi)編程的思想,對(duì)性能也有明顯的改善。我用簡(jiǎn)化的代碼來(lái)展示改版后的 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è)簡(jiǎn)易版的 namedtuple 就結(jié)構(gòu)就完成了,改進(jìn)后的 exec 調(diào)用中只有一行代碼,性能會(huì)更好,舊版本的還會(huì)額外 import 其他依賴(lài)。然后就是構(gòu)造元類(lèi)編程中類(lèi)屬性和方法了。屬性的獲取是通過(guò)寫(xiě)的 _getter 來(lái)完成,而實(shí)際上源碼上會(huì)委托給 operator.itemgetter 函數(shù)。

總結(jié)

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

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

相關(guān)文章

  • Python如何在for循環(huán)中同時(shí)使用兩個(gè)變量與兩個(gè)控制條件

    Python如何在for循環(huán)中同時(shí)使用兩個(gè)變量與兩個(gè)控制條件

    Python是一種廣泛使用的編程語(yǔ)言,其提供了許多強(qiáng)大的方法來(lái)處理代碼,Python?for循環(huán)是其中一種非常有用的方法,下面這篇文章主要給大家介紹了關(guān)于Python如何在for循環(huán)中同時(shí)使用兩個(gè)變量與兩個(gè)控制條件的相關(guān)資料,需要的朋友可以參考下
    2024-03-03
  • 使用Python自制一個(gè)回收站清理器

    使用Python自制一個(gè)回收站清理器

    經(jīng)常筆記本電腦的回收站存儲(chǔ)了很多的文件,需要打開(kāi)回收站全部選中進(jìn)行清理。這篇文章將使用Python自制一個(gè)回收站清理器,需要的可以參考一下
    2023-03-03
  • Python Opencv實(shí)現(xiàn)最強(qiáng)美顏濾鏡效果

    Python Opencv實(shí)現(xiàn)最強(qiáng)美顏濾鏡效果

    這篇文章主要介紹了如何利用Python OpenCV制作一個(gè)強(qiáng)大的美顏濾鏡效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以學(xué)習(xí)一下
    2022-03-03
  • Python中暫存上傳圖片的方法

    Python中暫存上傳圖片的方法

    這篇文章主要介紹了Python中暫存上傳圖片的方法,本文使用cStringIO模塊實(shí)現(xiàn)暫存功能,本文給出簡(jiǎn)單使用示例,需要的朋友可以參考下
    2015-02-02
  • pytorch torch.expand和torch.repeat的區(qū)別詳解

    pytorch torch.expand和torch.repeat的區(qū)別詳解

    這篇文章主要介紹了pytorch torch.expand和torch.repeat的區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • 人工智能學(xué)習(xí)Pytorch教程Tensor基本操作示例詳解

    人工智能學(xué)習(xí)Pytorch教程Tensor基本操作示例詳解

    這篇文章主要為大家介紹了人工智能學(xué)習(xí)Pytorch教程Tensor的基本操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-11-11
  • Python+Pygame繪制小球的實(shí)例詳解

    Python+Pygame繪制小球的實(shí)例詳解

    這篇文章主要為大家詳細(xì)介紹了如何利用Python?Pygame繪制小球(漸變大的小球、自由下落的小球、循環(huán)上下反彈的小球),感興趣的小伙伴可以了解一下
    2022-10-10
  • 如何利用Python處理excel表格中的數(shù)據(jù)

    如何利用Python處理excel表格中的數(shù)據(jù)

    Excel做為職場(chǎng)人最常用的辦公軟件,具有方便、快速、批量處理數(shù)據(jù)的特點(diǎn),下面這篇文章主要給大家介紹了關(guān)于如何利用Python處理excel表格中數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • python 爬取百度文庫(kù)并下載(免費(fèi)文章限定)

    python 爬取百度文庫(kù)并下載(免費(fèi)文章限定)

    這篇文章主要介紹了python 爬取百度文庫(kù)并下載的示例,幫助大家更好的理解和學(xué)習(xí)python 爬蟲(chóng)的相關(guān)知識(shí),感興趣的朋友可以了解下
    2020-12-12
  • Python+Flask實(shí)現(xiàn)自定義分頁(yè)的示例代碼

    Python+Flask實(shí)現(xiàn)自定義分頁(yè)的示例代碼

    分頁(yè)操作在web開(kāi)發(fā)中幾乎是必不可少的,而flask不像django自帶封裝好的分頁(yè)操作。所以本文將自定義實(shí)現(xiàn)分頁(yè)效果,需要的可以參考一下
    2022-09-09

最新評(píng)論