您可以使用標準庫中的tokenize模塊對Python源代碼進行標記。這將允許您查找腳本中使用的所有變量名稱。
現在假設我們將一個「非依賴關係」定義爲緊接在=
符號之前的任何變量名稱。然後,根據你的腳本代碼的簡單真的是(請參閱下面的注意事項),您可能能夠確定變量名不屬於非依賴這種方式:
import tokenize
import io
import token
import collections
import keyword
kwset = set(keyword.kwlist)
class Token(collections.namedtuple('Token', 'num val start end line')):
@property
def name(self):
return token.tok_name[self.num]
source = '''
C = A+B
D = C * 4
'''
lastname = None
names = set()
not_dep = set()
for tok in tokenize.generate_tokens(io.BytesIO(source).readline):
tok = Token(*tok)
print(tok.name, tok.val)
if tok.name == 'NAME':
names.add(tok.val)
lastname = tok.val
if tok.name == 'OP' and tok.val == '=':
not_dep.add(lastname)
print(names)
# set(['A', 'C', 'B', 'D'])
print(not_dep)
# set(['C', 'D'])
deps = dict.fromkeys(names - not_dep - kwset, 1)
print(deps)
# {'A': 1, 'B': 1}
注意事項:
如果您的腳本包含不是簡單 分配等語句,然後names
可能成爲填充不需要 變量名。例如,
import numpy
既能'import'
和'numpy'
添加到集合names
。
如果你的腳本包含一個分配,使得使用左手 側元組拆包,如
E, F = 1, 2
然後上面的天真代碼將只承認F
不是 依賴。
我想你可能是頑皮的,趕上前幾NameErrors –
我很調皮不提,我做的完全一樣@JakobBowyer建議;) – Giupo
的AST是不夠的。如果沒有完整的AST,全名解析和嚴格的數據流分析,您將無法爲除了非常簡單的腳本之外的任何其他工作而工作。由於Python是一種動態語言,即使是嚴重的數據流分析也不能提供體面的答案。如果你願意限制你的「Python」代碼非常簡單,那麼你可以建立一個可靠的分析器。你的問題是你的用戶不會注意你要施加的限制。所以除非用戶只是你,否則你不可能獲得好的結果。 –