对于我的一个项目,我有一个围绕python cmd类构建的python程序。这使我能够围绕发送到数据库的sql语句编写一种迷你语言。除了让连接python变得更容易之外,我还可以做sql不能做的事情。这对几个项目来说非常重要。然而,我现在需要添加if块以获得更大的控制流。
我目前的想法是,我将只向该语言添加两个新命令,IF和END。这些设置了一个变量,用于确定是否跳过一行。我想知道是否有其他人用cmd模块做过这件事,如果是,是否有我缺少的标准方法?谷歌似乎没有透露任何信息,cmd文档也没有透露任何内容。
想要一个与我正在做的事情相似的想法,请点击此处。欢迎提问和评论。:)
嗯,比我想的要复杂一点,不过有python语法会很好。在我最终完成之前,我讨论了很长一段时间来构建一种迷你语言。问题主要来自外部限制。我有一堆"数据",很慷慨,可以转化为sql。这是基于其他无法通过的"数据"。它对于问题的每个特定"版本"也是唯一的。将数据直接写入sql本来是我的第一个爱好,但并不实用。
出于好奇,我花了很多时间复习unix编程艺术中的迷你语言一章。
如果我用纯python构建这个东西,我就不会拥有解决问题集所绝对需要的灵活性。
制作"迷你语言"的局限性已经变得显而易见。
合适的语言具有树状结构,语法比cmd
更复杂。
有时,直接使用Python实际上比发明自己的DSL更容易。
目前,DSL可能会读取类似脚本的命令文件。
由于cmd
的工作方式,您的小注释会得到一个字符串参数,必须对其进行解析。然后执行命令。而且,每个命令都是cmd.Cmd
子类的一个方法。
以下是你能做的。
每个do_foo( self, args )
方法都成为一个独立的可调用对象。它将遵循命令设计模式。它将执行方法函数现在执行的操作。同样如此完全一样。
class Foo( object ):
def __init__( self, global_context ):
self.context= global_context
def __call__( self, args ):
... The rest of do_foo ...
此外,您现有的cmd.Cmd
子类可能会维护一些内部状态。所有self.this
和self.that
实例变量都必须更改为引用和显式上下文对象。
class Context( object ): pass
将self.this
或self.that
更改为self.context.this
或self.context.that
现在,您可以创建上下文和各种命令。
ctx = Context()
foo= Foo(ctx)
您的脚本会稍微更改语法。发件人:
foo argstring
bar argstring
至:
from mylanguage import foo, bar
foo( "argstring" )
bar( "argstring" )
这正是CLI现在所做的。不再。同样如此完全一样。语法略有不同。
现在,您的脚本不再位于难以扩展的DSL中。它是用Python编写的。
完成这些操作后,您现在可以使用Python语法if
语句。
您拥有当前在cmd
中实现的Exact功能,该功能具有更好的语法。
在进一步检查了问题集之后,我得出的结论是,我可以不使用迷你语言。它拥有我需要的所有功能,我没有时间从头开始重建项目。这是一个有趣的问题,如果我遇到同样的情况,我不再确定我会构建另一种迷你语言。OTOH,它在这里运行得很好,我不愿意放弃它所赋予的优势。