日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

Python骚操作:动态定义函数

發(fā)布時(shí)間:2025/3/20 python 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python骚操作:动态定义函数 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在 Python 中,沒有可以在運(yùn)行時(shí)簡(jiǎn)化函數(shù)定義的語法糖。然而,這并不意味著它就不可能,或者是難以實(shí)現(xiàn)。

from types import FunctionTypefoo_code = compile('def foo(): return "bar"', "<string>", "exec") foo_func = FunctionType(foo_code.co_consts[0], globals(), "foo")print(foo_func())

輸出:

bar

剖析

逐行檢視代碼,你會(huì)發(fā)現(xiàn)語言/解釋器的屏障是多么脆弱。

>>> from types import FunctionType

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

在本例中,help() 與 inspect 都可以完成工作,但是查看實(shí)際的源代碼,則會(huì)揭示出關(guān)于數(shù)據(jù)類型的更多細(xì)節(jié)。

''' 遇到問題沒人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:531509025 尋找有志同道合的小伙伴,互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書! ''' >>> from inspect import signature >>> signature(FunctionType) <Signature (code, globals, name=None, argdefs=None, closure=None)>

1. code

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

2. globals

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

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

3. name(可選)

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

4. argdefs(可選)

通過傳入一個(gè)包含任意類型的對(duì)象的元組,提供一個(gè)方式來供應(yīng)默認(rèn)參數(shù)值(def foo(bar="baz"))。(FunctionType((lambda bar: bar).__code__, {}, "foo", (10,))() == 10)。

5. closure(可選)

(如果需要在 CPython(PyPy,Jython,…)以外的其它 Python VM 中執(zhí)行,可能不應(yīng)該觸及,因?yàn)樗鼑?yán)重地依賴于實(shí)現(xiàn)細(xì)節(jié))。

一個(gè)cell 對(duì)象的元組。創(chuàng)建 cell 對(duì)象并非完全是直截了當(dāng)?shù)?#xff0c;因?yàn)樾枰{(diào)用 CPython 的內(nèi)部組件,但有一個(gè)庫可以令它更加方便:exalt(無恥的廣告)。(譯注:這個(gè)庫是作者開發(fā)的。)

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

compile() 是一個(gè)內(nèi)置方法,因此同時(shí)也是文檔豐富的。

exec 模式被用到,因?yàn)槎x函數(shù)需用多個(gè)語句。

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

聚合全部?jī)?nèi)容,并將動(dòng)態(tài)創(chuàng)建的函數(shù)指定給一個(gè)變量。

那個(gè)被前一句代碼編譯成的函數(shù),成為了生成的代碼對(duì)象的第一個(gè)常量,因此僅僅指向 foo_code 是不充分的。這是 exec 模式的直接后果,因?yàn)樯傻拇a對(duì)象可以包含多個(gè)常量。

>>> print(foo_func())

動(dòng)態(tài)生成的函數(shù)可以像其它函數(shù)一樣被調(diào)用。

總結(jié)

  • 除了做實(shí)驗(yàn),需要用到動(dòng)態(tài)創(chuàng)建函數(shù)的場(chǎng)景很少。

  • 玩耍(Toying around) Python 的內(nèi)部構(gòu)件是一種深入學(xué)習(xí)這門語言的好方法。

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

總結(jié)

以上是生活随笔為你收集整理的Python骚操作:动态定义函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。