Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在不使用重载的情况下开发程序的最佳方法_Python - Fatal编程技术网

Python 在不使用重载的情况下开发程序的最佳方法

Python 在不使用重载的情况下开发程序的最佳方法,python,Python,我从其他讨论中看到,重新加载被认为是一种不必要的操作,也是制定计划的一种糟糕方式。人们说使用doctest和unittest。我一定错过了什么。为了开发一个程序,我将它写在一个模块中,将模块加载到eclipse控制台中,在控制台中运行少量代码样本进行实验,然后发现模块中的错误,或者决定更改某些内容。当然,最快的方法是保存模块,重新加载模块,然后在控制台中继续工作。 有更好的办法吗 基本上,不要在控制台中尝试,而是通过编写测试来尝试。它的输入量几乎相同,但可重复(您可以检查在进行更改后是否仍能正常

我从其他讨论中看到,重新加载被认为是一种不必要的操作,也是制定计划的一种糟糕方式。人们说使用doctest和unittest。我一定错过了什么。为了开发一个程序,我将它写在一个模块中,将模块加载到eclipse控制台中,在控制台中运行少量代码样本进行实验,然后发现模块中的错误,或者决定更改某些内容。当然,最快的方法是保存模块,重新加载模块,然后在控制台中继续工作。

有更好的办法吗

基本上,不要在控制台中尝试,而是通过编写测试来尝试。它的输入量几乎相同,但可重复(您可以检查在进行更改后是否仍能正常工作),并且它是一种基本的文档形式。

下面是一个精心设计的示例,与在控制台输入代码进行测试相比,您可以使用和测试驱动开发,以递归阶乘函数为例:

控制台:

>>> factorial(7)
SyntaxError: invalid syntax
>>> factorial(7)
42
>>> factorial(7)
RuntimeError: maximum recursion depth reached        # StackOverflow! (basically)
>>> factorial(5)
120
第一次尝试:

def factorial(x)
    pass
def factorial(n):
    """Return the factorial of n, an exact integer >= 0.

    >>> [factorial(n) for n in range(6)]
    [1, 1, 2, 6, 24, 120]
    >>> factorial(30)
    265252859812191058636308480000000
    >>> factorial(-1)
    Traceback (most recent call last):
        ...
    ValueError: n must be >= 0

    Factorials of floats are OK, but the float must be an exact integer:
    >>> factorial(30.1)
    Traceback (most recent call last):
        ...
    ValueError: n must be exact integer
    >>> factorial(30.0)
    265252859812191058636308480000000

    It must also not be ridiculously large:
    >>> factorial(1e100)
    Traceback (most recent call last):
        ...
    OverflowError: n too large
    """

if __name__ == "__main__":
    import doctest
    doctest.testmod(verbose=True)
控制台:

>>> factorial(7)
SyntaxError: invalid syntax
>>> factorial(7)
42
>>> factorial(7)
RuntimeError: maximum recursion depth reached        # StackOverflow! (basically)
>>> factorial(5)
120
第二次尝试:

def factorial(x):
    return x*x-1
def factorial(x):
    return x * factorial(x-1)
控制台:

>>> factorial(7)
SyntaxError: invalid syntax
>>> factorial(7)
42
>>> factorial(7)
RuntimeError: maximum recursion depth reached        # StackOverflow! (basically)
>>> factorial(5)
120
第三次尝试:

def factorial(x):
    return x*x-1
def factorial(x):
    return x * factorial(x-1)
控制台:

>>> factorial(7)
SyntaxError: invalid syntax
>>> factorial(7)
42
>>> factorial(7)
RuntimeError: maximum recursion depth reached        # StackOverflow! (basically)
>>> factorial(5)
120
第四次尝试:

def factorial(x):
    if x == 0:
        return 1
    else:
        return x * factorial(x-1)
控制台:

>>> factorial(7)
SyntaxError: invalid syntax
>>> factorial(7)
42
>>> factorial(7)
RuntimeError: maximum recursion depth reached        # StackOverflow! (basically)
>>> factorial(5)
120
最后,我们得到了正确的答案,但在每个阶段,我们都必须回到控制台并编写相同的内容。对于这样一个简短的程序来说,这是可以的,但是对于一个具有许多功能、更复杂的交互和测试可能性的程序来说,这将需要很长的时间。编程是关于自动化重复的任务,而测试是一项重复的任务,所以自动化它是有意义的。在Python中,为您提供了实现这一点的工具

瞧,doctest模块:(示例取自文档)

第一次尝试:

def factorial(x)
    pass
def factorial(n):
    """Return the factorial of n, an exact integer >= 0.

    >>> [factorial(n) for n in range(6)]
    [1, 1, 2, 6, 24, 120]
    >>> factorial(30)
    265252859812191058636308480000000
    >>> factorial(-1)
    Traceback (most recent call last):
        ...
    ValueError: n must be >= 0

    Factorials of floats are OK, but the float must be an exact integer:
    >>> factorial(30.1)
    Traceback (most recent call last):
        ...
    ValueError: n must be exact integer
    >>> factorial(30.0)
    265252859812191058636308480000000

    It must also not be ridiculously large:
    >>> factorial(1e100)
    Traceback (most recent call last):
        ...
    OverflowError: n too large
    """

if __name__ == "__main__":
    import doctest
    doctest.testmod(verbose=True)
第一次测试(仅运行程序):

而且(如果您将所有测试用例添加到docstring中),现在您可以发布或集成程序或其他任何程序,并且它的bug比您每次更改某些内容时只测试那些您认为重要的内容要少得多,而不是您认为在开发过程开始时可能重要的事情

更不用说你现在已经有了文档的基础了!在控制台中运行该程序,然后输入
help(factorial)
将显示以下信息:

Help on function factorial in module __main__:

factorial(n)
    Return the factorial of n, an exact integer >= 0.

    >>> [factorial(n) for n in range(6)]
    [1, 1, 2, 6, 24, 120]
    >>> factorial(30)
    265252859812191058636308480000000
    >>> factorial(-1)
    Traceback (most recent call last):
        ...
    ValueError: n must be >= 0

    Factorials of floats are OK, but the float must be an exact integer:
    >>> factorial(30.1)
    Traceback (most recent call last):
        ...
    ValueError: n must be exact integer
    >>> factorial(30.0)
    265252859812191058636308480000000

    It must also not be ridiculously large:
    >>> factorial(1e100)
    Traceback (most recent call last):
        ...
    OverflowError: n too large
然后,您可以使用许多工具(标准库中有一个工具)将docstring转换为格式化的HTML帮助文件


当然,这只是可以与Python一起使用的许多测试工具之一。其他包括功能更强大的模块,以及在代码中添加
assert
语句的功能较弱的技术。

听说过测试驱动开发,它不同于滴答驱动的编程doctest和unittest用于测试。运行代码的一小部分不太可能捕获所有的bug,这不够严格或系统化。@sweeneyrod我同意系统化测试有着重要的地位,但有时我不想生成最后一段代码,我只想进行实验。即使我真的想在程序开发的早期制作一些经过适当测试的东西,我也只想尝试不同的想法。在那个阶段,我不会想到doctest会如此有用。这只会让我慢下来。你可以用你喜欢的任何方式进行实验,没有“最好的方法”进行实验。+1你的意思是在文件中编写语句,然后在将它们变成函数之前测试运行它们吗?那么,最快的方法是将测试文件加载(并重新加载)到控制台中吗?谢谢您的全面讨论。这对某些人来说很有趣,你可能猜他是python的noob(虽然不是数学编程的noob)。我的第一种方法是将函数写入文件,导入、运行、编辑、重新加载、运行、编辑等。为了检查我是否理解正确,doctest的优点是它可以同样快速地完成相同的事情并带来额外的好处,或者说它稍微慢一点,但由于额外的严格性而被认为是值得的?@hfffoman我想说,
doctest
的好处是,您最初做的工作稍微多一些,但这会减少长时间的写测试文件,然后再运行它,还有其他好处(文档会随着您的进行而编写)。但是我认为测试工具的威力随着你的程序变得越来越大而变得越来越明显——你永远不会梦想在没有正式测试和工具的情况下编写一个大型项目(比如Eclipse)——可能比标准库中的任务要重得多。