如何从Python';是阿斯特吗?

如何从Python';是阿斯特吗?,python,types,abstract-syntax-tree,Python,Types,Abstract Syntax Tree,假设我想从AST树中获取所有变量的类型,我已经从一些源代码中生成了这些变量——我该怎么做呢? 例如,假设在我的源代码中有类似于I=5的内容。如何从抽象语法树中确定I的类型是整数 我尝试了type()函数;但是,它在这种情况下不起作用。您不能,因为Python的变量没有类型值具有类型 这就是动态键入的工作原理。正如其他海报所指出的,在动态键入语言中,这并不容易。您不能像在C或Java中那样将赋值追溯到静态类型声明 然而,人们通常可以合理地确定类型 大概范围规则允许一个人确定在问题被问到的地方可以访

假设我想从AST树中获取所有变量的类型,我已经从一些源代码中生成了这些变量——我该怎么做呢? 例如,假设在我的源代码中有类似于
I=5
的内容。如何从抽象语法树中确定
I
的类型是整数


我尝试了
type()
函数;但是,它在这种情况下不起作用。

您不能,因为Python的变量没有类型具有类型


这就是动态键入的工作原理。

正如其他海报所指出的,在动态键入语言中,这并不容易。您不能像在C或Java中那样将赋值追溯到静态类型声明

然而,人们通常可以合理地确定类型


大概范围规则允许一个人确定在问题被问到的地方可以访问/更新/绑定哪些i(或哪一组i?)(“代码中此时的类型是什么?”)。然后可以对可能分配的所有值进行分析(一个特别简单的情况是,当我只绑定到函数定义时)。这些类型的类型格中的上界是i的“类型”。是的,在某些情况下,它可能是“任何东西”,但在大多数编写良好的程序中,甚至动态变量也有程序员想要的“窄”类型,通常是原始的langauge类型(比如,呃,“int”)。或者程序员无法合理地编写算法(什么,数组索引有时不是整数?)

您需要对程序进行某种保守的分析,以确定上限类型。(显然,您可以进行琐碎的分析,得出变量可以是“任意”类型的结论)。我认为这是一个不令人满意的答案


执行所有这些分析的机制非常复杂(需要全局流分析,并确定哪些内容可以动态加载才能真正做到这一点),我怀疑Python的AST包是否能做到这一点。

正如其他文章中所解释的,如果不仔细分析语法树,就很难实现这一点,python ast模块不提供任何工具

您仍然可以使用logilab的astng,它是pylint的基础,并提供静态推理功能

下面是一个简单的例子:

from logilab.astng.builder import ASTNGBuilder
builder = ASTNGBuilder()
astng = builder.string_build('i = 1', __name__, '<string>')
assnode = astng['']
print [(inf.value, type(inf.value)) for inf in assnode.infer()]
从logilab.astng.builder导入ASTNGBuilder
builder=ASTNGBuilder()
astng=builder.string\u build('i=1','u名称,')
assnode=astng[“”]
在assnode.infer()中为inf打印[(inf.value,键入(inf.value)]

当然,您必须挖掘api以获得更真实的使用。您仍然可以编写python-projects@lists.logilab.org关于这方面的帮助。

Hmm,好吧,假设我在某个时间点从代码节点获得的AST是:“a=2”模块([Assign([Name('a',Store())]),Num(2))…正如您所看到的,AST似乎显示分配的值的类型是num——有什么方法或函数可以在该节点上使用以获得此值吗?“什么,您的数组索引有时不是整数?”在我编写的一些代码中,这种情况可能会发生,因为我的数组有时不是一个
列表,它是一个
dict
@Nonomous:好吧,在代码中很明显,a的“类型”是字面上的“2”(nat的子集,int的子集,有理数的子集,实数的子集,虚数的子集,…).我不知道Python或AST模块,但您可以通过检查表达式来确定“a”的类型。如果它说“a=a+1”,您就麻烦了除非你检查到目前为止该数据流的所有其他值。你需要一个数据流分析模块。我怀疑它是Python的AST模块的一部分。可能是其他人建立了它,但他们必须大声说出来。@Ben:对于Python,你必须担心你的情况,但我认为我的观点是明确的。@IraBaxter:你的观点是明确的,而你呢很正确,在大多数Python代码中,给定变量只包含一种类型的值,或者可能是几种类型中的一种。但是你必须进行完整的程序分析才能观察到这一点,即使是这样,一个变量实际上可以有几乎任何类型的地方,也意味着任何涉及到它的变量都可以有几乎任何类型,以此类推,直到它被删除为止对于任何具有条件导入或动态类创建的程序,您需要解决停止问题,只需枚举程序中的所有类型。