1. 如何將字符串常量轉變為變量


參考並轉載:   https://mp.weixin.qq.com/s/-U0hKUvPBhFrhUdI0Ao3Og

 

1. 如何動態生成變量名?

   

已知 list = ['A', 'B', 'C', 'D'] , 
如何才能得到以 list 中元素命名的新列表
A = [], B = [], C = [], D = []呢?

 

就是將字符串內容作為其他對象的變量名

list 中的元素是字符串,此處的 ‘A’-‘D’ 是常量 ,而在要求的結果中,A-D 是變量 。

如果強行直接將常量當做變量使用,它會報錯:

 'A' = []
...SyntaxError: can't assign to literal

       報錯中的literal 指的是字面量 ,這是計算機科學中常見的一個概念,用於表達源代碼中的固定值。 例如,整數、浮點數、字符串等基本類型,就是字面量。

      字面量指的就是一個量本身,可以理解為一種原子性的實體,當然不能再被賦值了。

      所以,取出的字符串內容,並不能直接用作變量名,需要另想辦法。

      有初學者可能會想,list[0] = [] 行不行?當然不行,因為沒有出現 A 。那 A = list[0] ,接着 A = [] 呢?那也不行,因為這里的 A 是你憑空定義出來的,而不是從已有條件中生成的。

 

2. 解決辦法

2.1   global()

>>> list1 = ['A', 'B', 'C', 'D']
>>> for i in list1:
>>>     globals()[i] = []
>>> A
[]

       這個方法通過修改全局命名空間,巧妙地“定義”出了新的變量。globals() 方法取出來的是一個字典,字符串 ‘A’ 是其中一個鍵值(key),而這個鍵值恰恰是全局命名空間中的一個變量,這就實現了從常量到變量的轉化。

  在數據結構層面上,空列表 [] 作為一個值(value)跟它的字符串鍵值綁定在一起,而在運用層面上,它作為變量內容而跟變量名綁定在一起。

  看到這個回答的時候,我就突然想起來一篇文章,講的正是動態地進行變量賦值 的問題啊!我似乎只關注了 globals() 與 locals() 用法的區別,卻沒有真正地掌握它們的原初用途。

2.2   eval()動態執行代碼的方法

>>> list1 = ['A', 'B', 'C', 'D']
>>> for i in list1:
>>>     exec(f"{i} = []")
>>> A
[]

 

  他的寫法用到了 Python 3.6 才引入的 f-strings 特性,事實上,在較低版本中,也是可以實現的,只需要保證 exec() 方法接收的參數是包含了變量 i 的字符串即可,例如這樣寫:

# 以下代碼可替換上例的第 4 行
exec(i + " = []")
# 或者:
exec("{} = []".format(i))
# 或者:
exec(' '.join([i, '= []']))

 

  這幾種寫法的區別只是字符串拼接法的區別,關於如何拼接字符串,以及不同方法間的區別,參看《Python拼接字符串的七種方式》。

  這個答案的核心在於 exec() 方法,它是內置的,用途是執行儲存在字符串或文件中的代碼段。

它的基礎用法如下:

 

>>> exec('x = 1 + 2')
>>> x
3

# 執行代碼段
>>> s = """
>>> x = 10
>>> y = 20
>>> sum = x + y
>>> print(sum)
>>> """
>>> exec(s)
30

  看完了 exec() 的用法,我們再回來看 Q 同學的答案。for-循環中取出來的 i 是字符串,而拼接后的字符串經過 exec() 的處理,就獲得了動態編寫代碼的效果。

  也就是說,因為字符串常量的內容被當做有效代碼而執行了,其中的 'A'-'D' 元素,就取得了新的身份,變成了最終的 A-D 變量名。

  這個方法看起來很簡單啊,可是 exec() 方法太生僻,直到 Q 同學提出,我們才醒悟過來。

注意:在 Python3 中,exec() 是個內置方法;
而在 Python2 中,exec 是個語句(statement),另外有個 execfile() 方法,兩者相合並,
就成了 Python3 中的 exec() 方法。
本文使用的是 Python3。

 

3 總結

 

抽象一下最初的問題,

它實際問的是“如何將字符串內容作為其它對象的變量名”,

更進一步地講是——“如何將常量轉化為變量 ”。

使用直接進行賦值的靜態方法,行不通。

兩種方法都是間接的動態方法:

一個是動態地進行變量賦值,通過修改命名空間而植入變量;

一個是動態地執行代碼,可以說是通過“走后門”的方式,安插了變量。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM