我想检查一个字符串 - 它是一个导入命令吗?我试过了
# Helper - analyses a string - is it an import string?
"""
fromlike - from foo import bar
classic - import foo
classic_as - import foo as baz
"""
def check_is_import(string):
importname = ''
fromlike = False
classic = False
classic_as = False
if string[0:4] is 'from':
fromlike = True
importname = ''
if not fromlike and (string[0:6] is 'import'):
classic = True
importname = string.split(' ')[1]
if classic:
commandlist = string.split(' ')
if commandlist[2] is 'as':
classic_as = True
importname = commandlist[3]
del commandlist
if fromlike:
return ('fromlike', importname)
elif classic and (not classic_as):
return ('classic', importname)
elif classic_as:
return ('classic_as', importname)
else:
return ('no_import', importname)
但它适用于" fromlike"进口。 (注意:我没有问过"为什么这些代码不起作用?",我只是在搜索解决方案)什么代码肯定能检测到所有导入?基本上我的代码需要一小部分字符串。如果[0:4]
切片等于'from'
,则字符串为" fromlike import"。否则:如果[0:6]
切片等于'import'
,则该字符串为"经典导入"。如果它检测到'as'
,它将找到伪名称。此函数必须返回一个元组,该元组包含索引0下的导入类型和索引1下的导入模块名称。
答案 0 :(得分:2)
如果您想确保处理所有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