首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是否有工具静态地分析python代码,以确定可变参数是否为更改(检测副作用)?

是否有工具静态地分析python代码,以确定可变参数是否为更改(检测副作用)?
EN

Stack Overflow用户
提问于 2014-12-10 23:08:58
回答 1查看 265关注 0票数 4

是否有Python静态分析工具可以检测函数参数何时发生变异,从而导致副作用?

代码语言:javascript
运行
复制
that is
def foo(x):
    x.append("x at the end")

当x是一个列表时,将更改调用范围x。

能否可靠地检测到这一点?我之所以问这个问题,是因为这样一个工具可以使我们更容易地遵循纯功能方法。

我认为可以使用装饰器来警告它(用于开发),但这不像静态分析那样可靠。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-10 23:29:17

如果foo函数是用list-but调用的,那么它会变异它的参数--如果它是用不同的东西调用的,它可能会引发异常,或者做一些不改变它的事情。

类似地,您可以编写一个每次调用len时都会发生变异的类型,然后一个只打印其参数长度的函数就会变异它的参数。

更糟糕的是,如果您使用像+=这样的运算符,它将对具有它的类型调用(通常是变异的) __iadd__方法,比如list,但是在不具有(非变异) __add__方法的类型上调用(不变异)__add__方法,比如tuple。那么,在这种情况下你打算怎么做?

因此,如果传入迭代器,即使参数上的for循环也会发生变异,但是(通常)如果传递序列,则不会发生变异。

如果您只想列出频繁变异的方法名称和操作符,并搜索它们,那么作为AST访问者编写它就不难了。但这会给你带来很多假阴性和假阳性。

这正是静态类型设计所要解决的问题。Python没有构建静态类型,但是可以在Python的基础上构建。

首先,如果使用Python3.x,可以使用注释来存储参数的类型。例如:

代码语言:javascript
运行
复制
def foo(x: MutableSequence) -> NoneType:
    x.append("x at the end")

现在您知道了,从它需要一个MutableSequence (或一个list)而不是一个Sequence这一事实来看,它打算改变它的参数。而且,即使它现在没有这样做,将来的一些版本也可能会这样做,所以无论如何您都应该相信它的注释。

现在,您可以像在Haskell或ML中那样解决您的问题了:您的纯函数代码接受一个Sequence,它用那个Sequence调用函数,您只需要确保这些函数都没有定义为接受MutableSequence,对吗?

最后那部分是最难的部分。Python并没有阻止我写这个:

代码语言:javascript
运行
复制
def foo(x: Sequence) -> NoneType:
    x.append("x at the end")

为此,您需要一个静态类型检查器。Guido一直在推动注释标准化,允许形象化静态检查器成为Python的半官方部分。它还没有完全完成,而且它的类型系统也不如典型的类型化函数式语言那么强大,但它可以很好地处理大多数Python代码,满足您的需要。但是mypy并不是唯一可用的静态类型检查器;如果您搜索,还有其他的。

无论如何,使用类型检查器,foo函数将失败,并会出现一个错误,说明Sequence没有这样的方法append。另一方面,如果正确地将foo定义为接受MutableSequence,那么使用Sequence调用它的函数代码就会失败,从而导致解释Sequence不是MutableSequence的子类型的错误。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27412550

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档