|
|
1
2
总结 :这是编写编译器的常见方法,在这里很好。
在其他语言中处理此问题的一种非常常见的方法是“模式匹配”,这正是您所描述的。我想这就是它的名字
那么问题是,这种编程语言实现的常见习惯用法是Python中的反模式。噢。你可能会发现,这更多的是一个政治问题,而不是语言问题。如果其他Python主义者看到代码,他们会尖叫;如果其他语言实现者看到它,他们会立即理解。 这在Python中是一种反模式的原因是Python鼓励鸭子类型的接口:你不应该有基于类型的行为,而是应该由对象在运行时可用的方法来定义。 S. Lott's answer 如果你想让它成为地道的Python,它可以很好地工作,但它几乎没有增加什么。
我怀疑你的设计并不是真正的鸭子型——毕竟它是一个编译器,使用名称和静态结构定义的类非常常见。如果你愿意,你可以把你的对象想象成有一个“类型”字段
附录: 模式匹配可能是人们喜欢用函数式语言编写编译器等的首要原因。 |
|
|
2
2
python中有一条经验法则,如果你发现自己编写了一大块if/eif语句,并且条件相似(例如一堆isinstance(…)),那么你可能是用错误的方式解决了问题。
|
|
|
3
2
而不是实例,只需使用 Polymorphism
在需要强制的情况下,这样的事情怎么样?
这仍然是一个多态性问题。
|
|
|
4
1
文章没有攻击
是的,有更好的方法。或者几个。例如,您可以将类型的处理转换为函数,然后通过按类型查找来找到正确的函数。这样地:
更好的是,如果你能以某种方式避免进行任何类型的类型检查,但这可能很棘手。 |
|
|
5
0
在我使用Python 3编写的DSL中,我使用了Composite设计模式,因此节点在使用中都是多态的,正如S.Lott所建议的那样。
但是,当我一开始阅读输入以创建这些节点时,我确实使用了很多isinstance检查(针对Python 3提供的抽象基类,如collections.Iterable等,我相信它们也在2.6中),以及对hasattr的检查
使用isinstance进行此类测试比使用type()更通用,因为isinstance会捕获子类——如果你能对抽象基类进行测试,那就更好了。看 http://www.python.org/dev/peps/pep-3119/ 有关抽象基类的信息。 |
|
|
6
0
在这种特殊情况下,您似乎正在实现一个运算符重载系统,该系统使用对象的类型作为您要调用的运算符的选择机制。你的节点类型恰好相当直接地对应于你的语言类型,但实际上你正在编写一个解释器。节点的类型只是一段数据。 我不知道人们是否可以将自己的类型添加到您的领域特定语言中。但无论如何,我都会推荐一种表驱动的设计。 制作一个包含(binary_operator、type1、type2、result_type、evalfunc)的数据表。使用isinstance在该表中搜索匹配项,并有一些条件来选择某些匹配项。也许可以使用比表更复杂的数据结构来加快搜索速度,但现在你基本上是在使用长列表的ifelse语句来进行线性搜索,所以我打赌一个普通的旧表会比你现在做的稍微快一些。 我不认为isinstance在这里是错误的选择,主要是因为该类型只是您的解释器正在处理以做出决定的一段数据。双重分派和其他类似的技术只会掩盖你的程序正在做什么的真正内容。 Python中的一个巧妙之处是,由于运算符函数和类型都是第一类对象,因此您可以直接将它们填充到表中(或您选择的任何数据结构中)。 |
|
|
7
-1
|
|
|
Gengetsu · 如何从Bison中的语法启动变量? 8 年前 |
|
|
Jon Deaton · 如何使用元循环计算器引导Lisp解释器 9 年前 |
|
|
liyuan · 解释器如何翻译for循环? 9 年前 |
|
|
FlorianB · 用于解释HTML/CSS和获取元素样式的命令行工具 10 年前 |
|
|
ææç · 解释器交互模式保持文件打开的目的 12 年前 |
|
|
user3318845 · 字节码如何更快?[已关闭] 12 年前 |
|
|
Trung Bún · OCaml解释器:为什么我的解释器只执行文件中的一行 12 年前 |