是否需要“严格使用” Python编译器? [英] Is there a need for a "use strict" Python compiler?

查看:143
本文介绍了是否需要“严格使用” Python编译器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

存在 Python的静态分析工具,但编译时检查往往与运行时绑定相反哲学。可以 使用静态分析工具包装标准Python解释器,以强制执行某些使用严格的类似的约束,但是我们没有看到任何广泛采用这样的事情。



有什么关于Python的, 行为不必要或特别不受欢迎?



或者,尽管其广泛采用,但是Perl中的使用严格行为不必要了吗?



注意:必要我的意思是实际需要,而不是严格必要的。显然你可以不用使用严格来编写Perl,但是(从我看到的)大多数Perl程序员使用它。



注意:Python解释器 - 包装器不需要 require use strict类似的约束 - 你可以使用类似于use strict的伪pragma正常解释器。我不是在说添加语言级功能。






更新:解释use strict Perl的意见。 (链接到官方文档在第一段。)



use strict指令有三个不同的组件,其中只有两个非常有趣:




  • use strict vars:静态检查程序中词法变量的使用情况。 (请记住,在Python中,基本上只有全局作用域和 local 作用域)。许多Python指令检查这种事情。因为它是他们能做的唯一的静态分析,所以linters假设你使用直接的词法作用域,并警告你在这个意义上出现错误,直到你告诉他们闭嘴;

      FOO = 12 
    foo + = 3

  • use strict refs:禁止符号命名空间取消引用。 Python最接近的模拟是使用 locals() globals()进行符号绑定和标识符查找。



解决方案

Python拥抱的运行时绑定理念...使得使用严格行为不必要[和]特别不受欢迎



很好的总结。谢谢。



这本质上就是。静态分析工具不能帮助Python足够值得。






编辑



我要求我们内省为什么我们不需要它,相关地,为什么Perl程序员认为他们确实需要它。



这是为什么的原因正是你已经给出的原因。我们不需要它,因为它没有帮助。显然,你不喜欢这个答案,但没有什么可说的。编译时或预编译时间检查根本没有帮助。



但是,由于你花了时间再次提问,我会为你已经给出的答案提供更多的证据。



我写Java几乎和我写Python一样。 Java的静态类型检查不会防止任何逻辑问题;它不利于满足性能要求;它不能帮助满足用例。它甚至不会减少单元测试的量。



虽然静态类型检查确实发现了一个方法的偶然的滥用,你在Python中发现这一点很快。在Python中,你在单元测试时间发现它,因为它不会运行。注意:我不是说错误的类型被发现与许多聪明的单元测试,我说,大多数错误的类型问题是通过未处理的异常找到的东西根本不会运行足够远的测试断言。



Pythonistas不浪费时间在静态检查上的原因很简单。我们不需要它。它不提供任何价值。这是一个没有经济效益的分析水平。它不会使我更能够解决真正的人们对他们的真实数据有真正的问题。



查看最流行的SO Python问题是语言(不是问题域或库)相关。



在foo是None之间是否有任何差异。和foo == None? - == 。没有静态检查可以帮助这一点。另请参阅`==`和` is` in Python?



**(双星)和*(星)对参数有什么作用? - * x 给出一个列表, ** x 给出一个字典。如果你不知道这一点,你的程序会立即死亡,当你试图做一些不适合这些类型的东西。 如果你的程序从来没有做过什么不恰当的。然后你的程序工作。 'nuff说。



如何在Python中表示枚举? - 这是一种有限域类型的请求。具有类级别值的类几乎可以做到这一点。 如果有人更改作业,该怎么办?易于构建。覆盖 __ set __ 以引发异常。是静态检查可能会发现这一点。不,在实践中不会发生有人对一个枚举常量和一个变量感到困惑;当它们这样做时,在运行时很容易发现。 如果逻辑永远不会被执行怎么办。那么,这是糟糕的设计和单元测试差。抛出编译器错误并插入从未测试过的错误逻辑,比从未测试过的动态语言中发生的更好。



生成器表达式与列表解析 - 静态检查无助于解决此问题。



为什么1 +++ 2 = 3? - 静态检查不会发现这一点。 1 +++ 2 in C是完全合法的,尽管所有的编译器检查。它在Python中与C中的不一样,但只是合法。非常混乱。



Python列表列表,意外地反映在子列表中的更改 - 这是完全概念性的。静态检查也不能帮助解决这个问题。 Java等效项也会编译和行为不好。


There exist static analysis tools for Python, but compile time checks tend to be diametrically opposed to the run-time binding philosophy that Python embraces. It's possible to wrap the standard Python interpreter with a static analysis tool to enforce some "use strict"-like constraints, but we don't see any widespread adoption of such a thing.

Is there something about Python that makes "use strict" behavior unnecessary or especially undesirable?

Alternatively, is the "use strict" behavior unnecessary in Perl, despite its widespread adoption?

Note: By "necessary" I mean "practically necessary", not strictly necessary. Obviously you can write Perl without "use strict," but (from what I've seen) most Perl programmers do use it.

Note: The Python interpreter-wrapper need not require "use strict"-like constraints -- you could use a pseudo-pragma similar to "use strict" that would be ignored by the normal interpreter. I'm not talking about adding a language-level feature.


Update: Explaining what "use strict" does in Perl per comments. (Link to official docs is in the first paragraph.)

The "use strict" directive has three distinct components, only two of which are really interesting:

  • use strict vars: Statically checks lexically scoped variable usage in your program. (Keep in mind that, in Python, there is basically only global scope and local scope). Many Python linters check for this sort of thing. Since it's the only static analysis that they can do, the linters assume you use straightforward lexical scoping and warn you about things that appear wrong in that sense until you tell them to shut up; i.e.

    FOO = 12
    foo += 3
    

    If you're not doing anything fancy with your namespaces this can be useful to check for typos.

  • use strict refs: Prevents symbolic namespace dereferencing. Python's closest analog is using locals() and globals() to do symbolic binding and identifier lookup.

  • use strict subs: No real analog in Python.

解决方案

"the run-time binding philosophy that Python embraces... makes "use strict" behavior unnecessary [and] especially undesirable"

Pretty good summary. Thanks.

That is essentially it. Static analysis tools don't help Python enough to be worthwhile.


Edit

"I'm asking for us to introspect on why we don't need it and, relatedly, why Perl programmers think they do need it."

The reason why is precisely the reason you already gave. We don't need it because it doesn't help. Clearly, you don't like that answer, but there's not much more to be said. Compile-time or pre-compile time checking simply does not help.

However, since you took the time to asked the question again, I'll provide more evidence for the answer you already gave.

I write Java almost as much as I write Python. Java's static type checking does not prevent any logic problems; it doesn't facilitate meeting performance requirements; it doesn't help meet the use cases. It doesn't even reduce the volume of unit testing.

While static type checking does spot the occasional misuse of a method, you find this out just as quickly in Python. In Python you find it at unit test time because it won't run. Note: I'm not saying wrong types are found with lots of clever unit tests, I'm saying most wrong type issues are found through unhandled exceptions where the thing simply won't run far enough to get to test assertions.

The reason why is Pythonistas don't waste time on static checking is simple. We don't need it. It doesn't offer any value. It's a level of analysis that has no economic benefit. It doesn't make me any more able to solve the real problems that real people are having with their real data.

Look at the most popular SO Python questions that are language (not problem domain or library) related.

Is there any difference between "foo is None" and "foo == None"? -- == vs. is. No static checking can help with this. Also, see Is there a difference between `==` and `is` in Python?

What does ** (double star) and * (star) do for parameters? -- *x gives a list, **x gives a dictionary. If you don't know this, your program dies immediately when you try to do something inappropriate for those types. "What if your program never does anything 'inappropriate'". Then your program works. 'nuff said.

How can I represent an 'Enum' in Python? -- this is a plea for some kind of limited-domain type. A class with class-level values pretty much does that job. "What if someone changes the assignment". Easy to build. Override __set__ to raise an exception. Yes static checking might spot this. No, it doesn't happen in practice that someone gets confused about an enum constant and a variable; and when they do, it's easy to spot at run time. "What if the logic never gets executed". Well, that's poor design and poor unit testing. Throwing a compiler error and putting in wrong logic that's never tested is no better than what happens in a dynamic language when it's never tested.

Generator Expressions vs. List Comprehension -- static checking doesn't help resolve this question.

Why does 1+++2 = 3? -- static checking wouldn't spot this. 1+++2 in C is perfectly legal in spite of all the compiler checking. It's not the same thing in Python as it is in C, but just as legal. And just as confusing.

Python list of lists, changes reflected across sublists unexpectedly -- This is entirely conceptual. Static checking can't help solve this problem either. The Java equivalent would also compile and behave badly.

这篇关于是否需要“严格使用” Python编译器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆