- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在将我从 Scala 创建的领域特定语言的解释器移植到 Python。在这个过程中,我试图找到一种 pythonic 的方式来模拟我广泛使用的 Scala 的案例类功能。最后我求助于使用 isinstance,但我觉得我可能遗漏了一些东西。
文章如this one攻击 isinstance 的使用让我想知道是否有更好的方法来解决我的问题,而不涉及一些基本的重写。
我已经建立了许多 Python 类,每个类代表不同类型的抽象语法树节点,例如 For、While、Break、Return、Statement 等
Scala 允许像这样处理运算符求值:
case EOp("==",EInt(l),EInt(r)) => EBool(l==r)
case EOp("==",EBool(l),EBool(r)) => EBool(l==r)
到目前为止,为了移植到 Python,我已经广泛使用 elif block 和 isinstance 调用来实现相同的效果,但更加冗长和非 Pythonic。有没有更好的办法?
最佳答案
总结:这是一种常见的编译器写法,用在这里就好了。
在其他语言中处理此问题的一种非常常见的方法是“模式匹配”,这正是您所描述的。我希望这是 Scala 中那个 case
语句的名称。它是编写编程语言实现和工具的一个非常常见的习语:编译器、解释器等。为什么这么好?因为实现与数据完全分离(这通常很糟糕,但在编译器中通常是可取的)。
接下来的问题是,这种用于编程语言实现的常见习惯用法在 Python 中是一种反模式。呃哦。您可能会说,这更多是政治问题而不是语言问题。如果其他 Pythonista 看到代码,他们会尖叫;如果其他语言实现者看到它,他们会立即理解它。
这是 Python 中的反模式的原因是因为 Python 鼓励 duck 类型的接口(interface):你不应该有基于类型的行为,而是它们应该由对象在运行时可用的方法定义. S. Lott's answer如果您希望它是惯用的 Python,则可以正常工作,但它增加的很少。
我怀疑您的设计并不是真正的鸭子类型 - 毕竟它是一个编译器,并且使用名称定义的具有静态结构的类非常常见。如果愿意,您可以将对象视为具有“类型”字段,并且 isinstance
用于基于该类型进行模式匹配。
附录:
模式匹配可能是人们喜欢用函数式语言编写编译器等的首要原因。
关于python - 用 Python 编写解释器。 isinstance 是否被认为是有害的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1381845/
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我在摆弄 LinqToSQL 和 LINQPad,我注意到 SingleOrDefault() 没有对生成的 SQL 进行任何过滤或限制(我几乎期望与 Take(1) 等效)。 因此,假设您想保护自己
我是一名优秀的程序员,十分优秀!