1、如何動態(tài)生成變量名?M 同學的問題如下:
簡單理解,這個問題的意思是,將字符串內(nèi)容作為其它對象的變量名。 list 中的元素是字符串,此處的 ‘A’-‘D’ 是常量 ,而在要求的結(jié)果中,A-D 是變量 。 如果強行直接將常量當做變量使用,它會報錯: >>> 'A' = [] 報錯中的 字面量指的就是一個量本身,可以理解為一種原子性的實體,當然不能再被賦值了。 所以,取出的字符串內(nèi)容,并不能直接用作變量名,需要另想辦法。 有初學者可能會想,list[0] = [] 行不行?當然不行,因為沒有出現(xiàn) A 。那 A = list[0] ,接著 A = [] 呢?那也不行,因為這里的 A 是你憑空定義出來的,而不是從已有條件中生成的。 我覺得這個題目很有意思,值得玩味。因為,如果能解決這個問題,那就意味著可以不作預先定義,而是動態(tài)地生成變量名,這不僅能減少給變量取名的麻煩,還實現(xiàn)了自動編碼! 可以設(shè)想一下未來,人工智能在編寫代碼的時候,如果能根據(jù)已知條件,動態(tài)生成變量名,那編寫代碼的過程不就順利多了么?(據(jù)說,現(xiàn)在已經(jīng)有人工智能可以編寫代碼了,不知它在取變量名時,是用的什么方法?) 2、辦法總是有的
這個方法通過修改全局命名空間,巧妙地“定義”出了新的變量。globals() 方法取出來的是一個字典,字符串 ‘A’ 是其中一個鍵值(key),而這個鍵值恰恰是全局命名空間中的一個變量,這就實現(xiàn)了從常量到變量的轉(zhuǎn)化。 在數(shù)據(jù)結(jié)構(gòu)層面上,空列表 [] 作為一個值(value)跟它的字符串鍵值綁定在一起,而在運用層面上,它作為變量內(nèi)容而跟變量名綁定在一起。 看到這個回答的時候,我就突然想起來一篇文章,講的正是動態(tài)地進行變量賦值 的問題?。∥宜坪踔魂P(guān)注了 globals() 與 locals() 用法的區(qū)別,卻沒有真正地掌握它們的原初用途。 J 同學說,他正是看了那篇文章,才學得了這個方法。這就有意思了,我分享了一個自己囫圇吞棗的知識,然后它被 J 同學吸收掌握,最后反饋回來解決了我的難題。 我真切地感受到了知識分享的魅力:知識在流動中獲得生命,在碰撞中锃亮色澤。 同時,我也真切地明白了一個互助的學習團體的好處:利人者也利己,互助者共同進步。 3、動態(tài)執(zhí)行代碼的方法Q 同學提供了一個不同的答案: # Q 同學的解答 他的寫法用到了 Python 3.6 才引入的 f-strings 特性,事實上,在較低版本中,也是可以實現(xiàn)的,只需要保證 exec() 方法接收的參數(shù)是包含了變量 i 的字符串即可,例如這樣寫:
這幾種寫法的區(qū)別只是字符串拼接法的區(qū)別,關(guān)于如何拼接字符串,以及不同方法間的區(qū)別,參看《Python拼接字符串的七種方式》。 Q 同學這個答案的核心在于 exec() 方法,它是內(nèi)置的,用途是執(zhí)行儲存在字符串或文件中的代碼段。 它的基礎(chǔ)用法如下: >>> exec('x = 1 + 2') 看完了 exec() 的用法,我們再回來看 Q 同學的答案。for-循環(huán)中取出來的 i 是字符串,而拼接后的字符串經(jīng)過 exec() 的處理,就獲得了動態(tài)編寫代碼的效果。 也就是說,因為字符串常量的內(nèi)容被當做有效代碼而執(zhí)行了,其中的 'A'-'D' 元素,就取得了新的身份,變成了最終的 A-D 變量名。 這個方法看起來很簡單啊,可是 exec() 方法太生僻,直到 Q 同學提出,我們才醒悟過來。
4、總結(jié)抽象一下最初的問題,它實際問的是“如何將字符串內(nèi)容作為其它對象的變量名”,更進一步地講是——“如何將常量轉(zhuǎn)化為變量 ”。 使用直接進行賦值的靜態(tài)方法,行不通。 兩位同學提出的方法都是間接的動態(tài)方法:一個是動態(tài)地進行變量賦值,通過修改命名空間而植入變量;一個是動態(tài)地執(zhí)行代碼,可以說是通過“走后門”的方式,安插了變量。 兩種方法殊途同歸,不管是白貓還是黑貓,它們都抓到了老鼠。 這兩種方法已經(jīng)給我們帶來了很有價值的啟發(fā),同時,因為它們,群內(nèi)小伙伴們更是發(fā)散地討論一些相關(guān)聯(lián)的話題,例如:S 同學提出了另一種修改命名空間中變量的寫法、L 同學提到了 eval() 的意義、eval() 與 exec() 的區(qū)別、我查到了為什么要慎用 eval() 、C 與 H 同學提到了 eval() 的安全用法…… 雖然,某些話題無法在群聊中充分展開,但是,這些話題知識的延展聯(lián)系,大大地豐富了本文開頭的問題,這一個微小的問題,牽連出來了兩個大的知識體系。 |
|
來自: LibraryPKU > 《Python》