如果要確保處理所有Python導入窗體,請讓Python執行解析。使用ast.parse()
function並使用生成的分析樹;你要麼得到Import
或ImportFrom
對象:
| Import(alias* names)
| ImportFrom(identifier? module, alias* names, int? level)
每個alias
由名稱及其用於導入名字可選標識符爲:
-- import name with optional 'as' alias.
alias = (identifier name, identifier? asname)
注意,可以有多個進口!您可以導入classic
或fromlike
,並且都可以導入多個名稱。你的函數需要返回一個列表的(type, name)
元組。對於無效輸入,拋出一個異常(ValueError
是一個不錯的選擇此處):
import ast
def check_is_import(string):
try:
body = ast.parse(string).body
except SyntaxError:
# not valid Python
raise ValueError('No import found')
if len(body) > 1:
# not a single statement
raise ValueError('Multiple statements found')
if not isinstance(body[0], (ast.Import, ast.ImportFrom)):
raise ValueError('No import found')
type_ = 'classic' if isinstance(body[0], ast.Import) else 'fromlike'
results = []
for alias in body[0].names:
alias_type = type_
if alias.asname:
alias_type += '_as'
results.append((alias_type, alias.asname or alias.name))
return results
的方法或許應該改名爲extract_import_names()
,因爲這反映了它要好得多。
演示:
>>> check_is_import('from foo import bar')
[('fromlike', 'bar')]
>>> check_is_import('import foo')
[('classic', 'foo')]
>>> check_is_import('import foo as baz')
[('classic_as', 'baz')]
>>> check_is_import('from foo import bar, baz as spam, monty as python')
[('fromlike', 'bar'), ('fromlike_as', 'spam'), ('fromlike_as', 'python')]
>>> check_is_import('import foo as baz, baz, spam as ham')
[('classic_as', 'baz'), ('classic', 'baz'), ('classic_as', 'ham')]
>>> check_is_import('invalid python')
Traceback (most recent call last):
File "<stdin>", line 3, in check_is_import
File "/Users/mjpieters/Development/Library/buildout.python/parts/opt/lib/python3.6/ast.py", line 35, in parse
return compile(source, filename, mode, PyCF_ONLY_AST)
File "<unknown>", line 1
invalid python
^
SyntaxError: invalid syntax
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in check_is_import
ValueError: No import found
>>> check_is_import('import foo; import bar')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 9, in check_is_import
ValueError: Multiple statements found
>>> check_is_import('1 + 1 == 2')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 11, in check_is_import
ValueError: No import found
爲什麼有一隻狗,何必自己嗎?使用['ast.parse()'](https://docs.python.org/3/library/ast.html#ast.parse)並查看生成的AST樹。 –
@MartijinPieters請給我一個例子。 –
在編寫答案的過程中。 :-) –