【问题标题】:Python input file containing commands to be executed包含要执行的命令的 Python 输入文件
【发布时间】:2018-02-02 19:39:32
【问题描述】:

我正在做一个练习,我正在创建基于 Python 列表创建和修改堆栈的 Python 3 函数。我的函数名称包括:createstack()pop()push() 等。 是否可以创建一个输入文本文件,其中包含将执行各种功能的一系列命令?我目前的代码结构是:

def createstack():
.
.
def pop(stackin,data):
.
.
.
def push(stackin,data):
.
.
.
#main

我可以通过编码来测试功能,例如在代码的主要部分中push(stack3,"dog")。 我可以通过将pushpopcreatestack 等放在一个文件中来实现相同的测试,并且我的例程可以读取文件然后执行每一行,就好像它在我的 Python 模块的主要部分中一样?

我正在使用 IDLE 开发和运行代码。

【问题讨论】:

  • 我看到了 2 种方法:1. 使用 eval 2. 制作另一个 python 可执行文件,在其中导入第一个具有必要功能的 python 文件并调用它们
  • 你好 Andrew,对于选项 2,你的意思是......创建一个新的“harness”模块,其中 import crlstack 位于“harness”的顶部 - 效果是 import “引入”包含我的 push()、pop()、createstack() 等的源代码?然后在“线束”中我编码: stack1 = createstack(), stack1 = push(stack1,"dog)? 作为一个附带问题,如果我的导入模块被编写为一个类,则“线束”中调用的语法将是:stack1.push("dog") ?
  • 请勿使用eval。这是不安全的,还有更好的解决方案。
  • 是的,导入“引入”在导入模块中编写的代码,正如您在答案中给出的教程中看到的那样。下一个问题:好吧,这取决于您如何导入它。如果喜欢from crlstack import createstack, ...,那么可以,但如果只是喜欢import crlstack - 不,您将不得不致电crlstack.createstack()。最少的导入方式降低了命名冲突的风险
  • 最后一个问题:你的意思是,Stack 类是在导入的模块中定义的?然后您首先必须通过调用stack1 = [crlstack.]Stack(...) 创建该类的实例,之后您将能够调用该类的任何方法,例如stack1.push(...)

标签: python python-3.x unit-testing


【解决方案1】:

你应该看看这个教程,你应该并且可以从其他 python 文件中导入你的文件:

https://en.wikibooks.org/wiki/A_Beginner%27s_Python_Tutorial/Importing_Modules

【讨论】:

  • 看起来(如上面 Andrew Che 的评论),导入是一种非常“干净”的方式来做到这一点。谢谢。
  • 绝对!我只是想向您指出一个完整的解释,可以帮助您有更广泛的理解
【解决方案2】:

正如他们所说,正确的做法是导入模块并将其作为常规 python 文件运行,如果你真的想要纯文本文件,可以购买一些玩具语言,例如:

push, "dog"
push, 3
push, False
pop
pop

然后做一些事情来解析它:

from mystack import createstack, push, pop

class MyLangParser:
    COM_POP = "POP"
    COM_PUSH = "PUSH"

    def __init__(self):
        self.stack = createstack()

    def push(self, val):
        push(self.stack, val)

    def pop(self):
        return pop(self.stack)

    def parse(self, filename):
        with open(filename, "r") as f:
            data = f.readlines()
        for line in data:
            self.parse_line(line)
            print(self.stack)

    def parse_line(self, line):
        try:
            command, val = line.split(",")
            if command.strip().upper() == self.COM_PUSH:
                self.push(eval(val.strip())) # I don't like this, but it is the easiest (most dangerous) way.
            elif command.strip().upper() == self.COM_POP:
                self.pop()
            else:
                raise SyntaxError("Command not recognized")
        except ValueError:
            if line.strip().upper() == self.COM_POP:
                self.pop()
            else:
                raise SyntaxError("Command not recognized")

if __name__ == "__main__":
    parser = MyLangParser()
    parser.parse(sys.argv[1])

用前面的例子,和下面的函数

def createstack():
    return []

def push(alist, val):
    alist.append(val)

def pop(alist):
    return alist.pop()

输出是:

['dog']
['dog', 3]
['dog', 3, False]
['dog', 3]
['dog']

我希望你认识到这样做的正确方法是从其他 python 文件中导入模块。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-21
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 2014-08-07
    • 1970-01-01
    相关资源
    最近更新 更多