我讨厌Python静态类型标注方案

2020-10-31 07:54:02

基本上。我并不讨厌Python类型的批注-在我看来:int=0没有什么错。但是,每当我不得不看任何给定的冗长的废墟时,这双眼睛确实会有点流血,这就是打字模块鼓励人们写作的那种杂乱无章的东西。

类型模块,以及它最好的Mypy静态分析器和Linter,已经预先劫持了两个看似有用的新的、不可靠的Python类方法:__CLASS_GETIEM__(…)。和__MRO_条目__(…)。,根据它们的介绍性PEP,除了实现键入内部部件(q.v.。小节尾注小节)。哪一个哦来吧。滥用Dunder方法使Python成为Python。我们怎么才能显性地表达出来,这比含蓄要好呢?Python不是最近才添加了__matmul__(…)吗。朋友们,他们甚至没有像标准库中的任何地方那样的默认实现??呃.。当人们像狗屎一样拉屎时,他们是否应该“滥用”__truediv_(…)?(?和__rtruediv__(…)。笨蛋会被打上某种新的MethodOffLimitsError吗?!

说到MyPy,我担心它的开发正在推动类型语法和语义的设计,而且它的版本是0.70。我直截了当地说:我不喜欢我的Py。我不喜欢它的前提-程序的紧急类型学是其功能的本质所固有的;使用linting阶段处理它-就像处理格式错误的文档字符串或方法defs周围的多余换行符一样-发出了错误的消息。

我也不喜欢MyPy目前的表现。我有一个项目,它在几个Python模块中有一些基本定义:ABC、布尔谓词、字符串化实用程序、&;c&;c。然后用它们来构建松散的数据结构层次结构,然后用它们来构建一些可互操作(希望是可扩展的)基本应用程序。因此,就像芝士汉堡一样,就有多少层,以及这些层是如何构建和利用彼此的。对吗?因此,在如此低的级别上正确获取导入非常重要,以避免循环依赖和优先级反转之类的事情。嗯,所以。因为MyPy是一个静态分析器,所以它必须表示目标Python程序,而不实际执行它。在某些方面,它非常顺利地做到了这一点--Python的标准库提供了(比方说)使用中间抽象语法图和解释器内部结构的API。不过,有些东西相当粗糙,特别是MyPy分析进口的方式需要从无到有,从无到有地重新实现。上次我检查时,它没有区分模块级的import语句和那些包含在函数和方法defs中的语句,这很奇怪。它也不知道如何处理那些没有引用直接的超普通标准的、普通的基于文件的代码模块的导入-考虑到在获得sys.meta_path导入钩子的过程中发生了多少API波动,你会认为MyPy阴谋集团的某个人会注意到这种狗屎般的事情吗,n‘est ce Pas?

输入提供的类型和注释给代码增加了大量的可视噪声。

…。这是我去年写的东西,当时我以TX的身份进行输入打字,试图减轻人们不得不退出打字的荒谬稻草人类型的雪崩。我尤其对__槽__成员的必要注释(ClassVar[Tuple[str,...]])感到恼火。位),因为a)要求ClassVar注释包含类成员的类型提示,以及b)使用...。标记,以指示它是齐次不变量。操我。不如干脆:

…。这实际上有点奇怪,也许不是。人力资源管理。集思广益是没有评判的。我甚至不介意这样的事情:

…。稍后将详细介绍尖括号语法的含义。但是是啊,是啊!我们已经为解释器中的标识符提供了Unicode支持,让我们使用它吧!将别名省略到更高的代码点!是的,这个例子有点离题,但你知道我在说什么。

类型模块依赖于虚拟类型的并行层次结构来表示内置内容并消除某些语法细微差别的歧义。

…。有点他妈的可笑。进口所有这些假名字是粗俗和粗俗的。甚至是无脊椎动物。首先,请看:所有这些东西的作者都或多或少地承认了这一事实-以至于起草了一份PEP来解释这一特殊的逻辑错误,并建议通过折旧键入中所有重复的虚拟类型(因此键入.Dict和键入.List和键入.Str,&;c)来解决这个问题,并使实际的内置使用“类型参数”。

我把最后一位放在引号中是因为,第二,使用下标运算符(née‘括号’,或[…])的整个过程。在TypeName上也是我认为相当令人讨厌的事情。

借助于一些解释,请允许我停下来片刻,在我个人观点的迷雾中给您一个或两个方向:我他妈的热爱C++。我真他妈的爱死它了。我意识到这只是少数人的观点;大多数有丰富领域经验的人都可以熟练地列举出无数理由,说明为什么C++是编程时代精神上令人厌恶的混乱的幻想瘟疫;我读过他们的有趣帖子,同时试图理解在某个漫长的深夜意外抛出的一些C++曲线。

请看最后一点,关于它的禅宗状态,以及C++是如何与其说是真正面向对象的,不如说是面向结构的-这些都是我对该语言热爱的基础。在这一点上,我可能应该注意到,我直到2012年才完全沉浸在学习中,那是在2011年之后,也就是C++11发生的时候,这是一个很大的问题(如果您还没有意识到的话)。

但是,是的,我通常最讨厌的语言是爪哇--这是一种我个人可以立即系统地、公正地诋毁和诋毁的语言。我赢得了厌恶爪哇的权利。我针对有史以来第一个他妈的商用servlet容器(JRun 1.0 Dogg)编写了n层Web服务体系结构,然后涉水穿过了可怕的JSP泥潭;我编写了几个ORM,甚至一个FRM(所有这些都非常不可靠,但它们都有效);我浪费了6到8个小时来调试一些肯定是黑暗、无形和邪恶的东西,就像地球上曾经出现过的任何东西一样邪恶-最后才发现$CLASSPATH中的几个错放的字符是导致危机的原因。在调试过程中,我浪费了6到8个小时来调试肯定是黑暗、无形和邪恶的东西-最后才发现$CLASSPATH中的几个错放的字符是导致危机的原因。我使用的是JBoss。我使用的是WebSphere。

近年来,我的小便和醋都蒸发了,所以我可以克制住不告诉例如我在酒吧遇到的完全陌生的人为什么有人把java.lang.ClassLoader细分为java.lang.ClassLoader是一个精神上贫穷的反社会者,需要一个好的公开鞭打-老实说,我不再是那个人了。我想我就是那个二十多岁的人,如果你当时认识我,不得不听我在这类话题上的胡言乱语,我个人向你道歉。

但是,是的,所以,重点是。好的。问题是,在我这种经受过战斗考验和经过时间考验的分类学反感中,我认为我对Java语言的“泛型”有最大的原始反Java怒火。

有一段时间,Java没有泛型。这不是什么大不了的事;它的引擎盖下的一切都是指针,内部的所有东西都无情地与系统字长对齐(我认为?)-而且,由于“Java”同时是语言、运行时、虚拟机执行环境和标准类库,它可以依赖(几乎)每个对象实例的类从一个单独的根对象类派生出来。

最后一个事实使得Java中的强制转换与(比方说)C++中的转换有很大的不同。在内部,Java运行时可以更改CASTEE的类型签名元数据记录,该记录属于s/typeName/Castname/g类型。

与之形成鲜明对比的是,在“C++转换与转换”中有一整篇博士论文,其中包含非常具体、棘手的规则和规则。因此,无论你觉得这些规定令人恼火,还是(对我来说)是一种早就应该的逻辑和秩序的药膏,在某种程度上缓解了自己思想无休止的强迫性回流搅动(…),这都无关紧要。我们都同意Java中的强制转换与C++中的强制转换完全不同。

但就像Java负责人做出的许多其他决策一样,他们以一种看起来像他们知道的方式向语言添加了“泛型”,而不考虑它的行为方式。JAVA泛型的工作方式类似于具有单个根的对象层次结构中的向上和向下强制转换;C++最接近的是Dynamic_Cast<;…。>;()-但是C++类型的元数据甚至不是一个运行时的东西,它们的行为完全不同。C++中的强制转换要么重新解释内存,要么调用类型转换操作符,或者可能两者兼而有之。如果向下转换的实例是临时通过值传递的,则向下转换实例(即使通过一个简单的、无分支类型的塔)也可以在内存中“分割”该对象。

我离题了,不是吗?这实际上是说我不喜欢他们在Java中所做的事情--那就是:他们让泛型看起来有点像C++模板,尽管它们的行为并不像C++模板。他们对泛型类型的“专门化”和声明使用了类似的尖括号语法。但是后来发现,他们不得不添加一堆奇怪的狗屎,这些狗屎不会立即有意义-比如问号类型名称通配符之类的表达式-这会导致在尝试执行所有这些通用Java时需要记住“pes”。

但这都是胡说八道,不是吗?我对javac一无所知,也不知道它是如何优化东西的,也不知道JVM中的子系统上的许多奢侈系统都在努力使您的代码执行得最完美。但是我确实知道Java泛型使用“类型擦除”-泛化表达式实际上不会给类型带来适当的操控,这意味着JVM正在管理的所有元数据都被忽略了,就像当您这样做时,可以这样说:

专家们一致认为:这并不是更快,也不是更好。Java泛型看起来像C++模板,这是一个神秘的特性,人们可以用它来打造一条通向最优的道路-但它们的作用就像是一个动态低迷的人的一大块耸肩。

所以是的-这就是我的感受。现在你认识他们了。奇怪的是,写下这篇文章让我想再次用Java编程-如果没有其他原因,就是为了保持允许我他妈的讨厌Java的经验诚意。但是,你也知道,当有事情困扰你的时候,仔细仔细地看一看它,看看到底是什么在困扰着你,以及它是如何工作的,这通常是很有启发性的。是。