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