Python 3:检查字符串是否为导入命令
我想检查一个字符串-它是一个导入命令吗?我试过了Python 3:检查字符串是否为导入命令,python,python-3.x,Python,Python 3.x,我想检查一个字符串-它是一个导入命令吗?我试过了 # 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
# 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)
但它对类似进口的产品起到了作用。注意:我不是在问为什么这段代码不起作用,我只是在搜索一个解决方案,什么代码肯定能检测到所有导入?基本上,我的代码从字符串中抽取一部分。如果[0:4]切片等于“from”,则该字符串是类似于from的导入。否则:如果[0:6]切片等于“import”,则该字符串为经典导入。如果它检测到'as',它将找到伪名称。此函数必须返回一个元组,该元组包含索引0下的导入类型和索引1下的导入模块名称。如果要确保处理所有Python导入表单,请让Python进行解析。使用和使用生成的解析树;您将从对象中获取Import或ImportFrom: 每个别名都包含一个名称和可选标识符,用于将名称导入为: 请注意,可以有多个导入!您可以使用classic或fromlike导入,两者都可以导入多个名称。函数需要返回类型、名称和元组的列表。对于无效输入,请在此处引发异常值错误:
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
可能应该重命名该方法以提取\u import\u名称,因为这反映了它做得更好
演示:
你为什么要养条狗自己叫?使用并查看生成的AST树。@MartiInputers请给我一个例子。在写答案的过程中:-多个名字应该怎么办?将foo、bar、baz作为垃圾邮件导入?与将它们作为单独的导入命令导入相同,但返回“classic_multi__as”,“spam”错误!在问题中解释。
-- import name with optional 'as' alias.
alias = (identifier name, identifier? asname)
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
>>> 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