国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Python騷操作:動態定義函數

rottengeek / 1829人閱讀

摘要:可選控制所返回的函數的屬性。模式被用到,因為定義函數需要用多個語句。聚合全部內容,并將動態創建的函數指定給一個變量。寫完之后,我偶然發現,在自己列的計劃轉載清單中,有這一篇相關的文章,它介紹了動態定義函數的方法。


標題:Python Tips: Dynamic function definition

作者:Philip Trauner

譯者:豌豆花下貓

鏈接:https://philip-trauner.me/blo...

基于 MIT 許可協議

在 Python 中,沒有可以在運行時簡化函數定義的語法糖。然而,這并不意味著它就不可能,或者是難以實現。

from types import FunctionType

foo_code = compile("def foo(): return "bar"", "", "exec")
foo_func = FunctionType(foo_code.co_consts[0], globals(), "foo")

print(foo_func())

輸出:

bar
剖析

逐行檢視代碼,你會發現語言/解釋器的屏障是多么脆弱。

>>> from types import FunctionType

Python 文檔通常不會列出那些非用于手動創建的類的特征(這是完全合理的)。有三種方法可以解決這個問題:help()、inspect(無法查看內置方法)、以及最后的解決方案,即查看 CPython 源代碼。

在本例中,help() 與 inspect 都可以完成工作,但是查看實際的源代碼,則會揭示出關于數據類型的更多細節。

>>> from inspect import signature
>>> signature(FunctionType)
1. code

內部是一個PyCodeobject ,作為types.CodeType 對外開放。非內置方法擁有一個__code__ 屬性,該屬性保存了相應的代碼對象。利用內置的 compile() 方法,可以在運行期創建types.CodeType 對象。

2. globals

如果一個函數引用的變量不是在局部定義的,而是作為參數轉入、由默認參數值提供、或者通過閉包上下文提供,則它會在 globals 字典中查找。

內置的 globals() 方法會返回一個對當前模塊的全局符號表(global symbol table)的引用 ,因此能被用來提供一個總是與當前表的狀態相一致的字典。傳入任意其它的字典也是可以的(FunctionType((lambda: bar).__code__, {"bar" : "baz"}, "foo")() == "baz")。

3. name(可選)

控制所返回的函數的__name__ 屬性。只真正對 lambdas 有用(由于匿名性,它們通常沒有名稱),并且重命名函數。

4. argdefs(可選)

通過傳入一個包含任意類型的對象的元組,提供了一個方式來供應默認參數值(def foo(bar="baz"))。(FunctionType((lambda bar: bar).__code__, {}, "foo", (10,))() == 10)。

5. closure(可選)

(如果需要在 CPython(PyPy,Jython,...)以外的其它 Python VM 中執行,可能不應該觸及,因為它嚴重地依賴于實現細節)。

一個cell 對象的元組。創建 cell 對象并非完全是直截了當的,因為需要調用 CPython 的內部組件,但有一個庫可以令它更加方便:exalt (無恥的廣告)。(譯注:這個庫是作者開發的。)

>>> foo_code = compile("def foo(): return "bar"", "", "exec")

compile() 是一個內置方法,因此同時也是文檔豐富的。

exec 模式被用到,因為定義函數需要用多個語句。

>>> foo_func = FunctionType(foo_code.co_consts[0], globals(), "foo")

聚合全部內容,并將動態創建的函數指定給一個變量。

那個被前一句代碼編譯成的函數,成為了生成的代碼對象的第一個常量,因此僅僅指向 foo_code 是不充分的。這是 exec 模式的直接后果,因為生成的代碼對象可以包含多個常量。

>>> print(foo_func())

動態生成的函數可以像其它函數一樣被調用。

結尾

除了做實驗,需要用到動態創建函數的場景很少。

玩耍(Toying around) Python 的內部構件是一種深入學習這門語言的好方法。

如果需要,可以毫不費力地越過解釋器/語言的界線。

還是一如既往地:不要濫用語言 (好吧,一點點也無妨,對吧?)

--------(譯文完)--------

花下貓語: 在上一篇《Python進階:如何將字符串常量轉為變量?》中,我介紹了兩種動態修改變量 的方法(globals() 與 exec())。寫完之后,我偶然發現,在自己列的“計劃轉載清單”中,有這一篇相關的文章,它介紹了動態定義函數 的方法。因為它的相關度太大,而篇幅又是那么小(核心代碼只有三行,文中其它內容都是在解釋其背后的原理),我覺得如果翻譯出來的話,效果會更好,所以就抓緊時間翻譯出來了。建議與前一篇文章配合閱讀。

公眾號【Python貓】, 專注Python技術、數據科學和深度學習,力圖創造一個有趣又有用的學習分享平臺。本號連載優質的系列文章,有喵星哲學貓系列、Python進階系列、好書推薦系列、優質英文推薦與翻譯等等,歡迎關注哦。PS:后臺回復“愛學習”,免費獲得一份學習大禮包。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/43393.html

相關文章

  • 深度辨析 Python 的 eval() 與 exec()

    摘要:內置函數們能夠被提拔出來,這就意味著它們皆有獨到之處,有用武之地。因此,掌握內置函數的用法,就成了我們應該點亮的技能。報錯包含了內置命名空間中的名稱,在控制臺中輸入,就能發現很多內置函數異常和其它屬性的名稱。 Python 提供了很多內置的工具函數(Built-in Functions),在最新的 Python 3 官方文檔中,它列出了 69 個。 大部分函數是我們經常使用的,例如 p...

    AndroidTraveler 評論0 收藏0
  • Python 操作,自動拷貝U盤

    摘要:今天的騷操作,分享的是一個自動拷貝電腦盤內容的程序。當別人的盤插入到你的電腦上時,腳本會自動把盤所有的內容,全部拷貝到你的電腦上。騷源碼程序主要是由三個函數組成,。每個操作都會記錄到日志中,以便日后查看相應的拷貝信息。 showImg(https://segmentfault.com/img/remote/1460000016794520); 閱讀文本大概需要 6 分鐘。 Python...

    zgbgx 評論0 收藏0
  • Python 操作,微信遠程控制電腦

    摘要:今天帶給大家一個非常有意思的程序,基于實現微信控制電腦。你可以通過在微信發送命令,來拍攝當前電腦的使用者,然后圖片會發送到你的微信上。程序主要是通過使用庫來登錄到微信網頁端,然后通過來發送消息和接收消息。隨后會彈出一個微信網頁登錄的二維碼。 showImg(https://segmentfault.com/img/remote/1460000016807619); 閱讀文本大概需要 5...

    ytwman 評論0 收藏0
  • 經驗拾憶(純手工)=> Python好用深度技能工具介紹

    摘要:單元素元祖這是整數這才是元祖也許這兩行,你們當時疑惑過,并且現在也都知道了,當然重點并不在這里。。雖然我水平很垃圾,但是我知道匿名函數有一種執行方式叫做自執行。看吧,這就是版的匿名函數自執行方法。 單元素元祖: a = (1) # 這是整數1 a = (1,) # 這才是元祖 也許這兩行,你們當時疑惑過,并且現在也都知道了,當然重點并不在這里。。 我無聊的時候想過,為什么單...

    UnixAgain 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<