【问题标题】:Python input and exceptions vs. C++Python 输入和异常与 C++
【发布时间】:2013-04-14 18:29:59
【问题描述】:

我想以 Python 方式尽可能接近地复制以下 C++ 代码,其中包含输入和异常处理。我取得了成功,但可能不是我想要的。我本来想退出类似于输入随机字符的 C++ 方式的程序,在这种情况下它是一个“q”。 while 条件下的 cin 对象不同于 python 的方式使 while 为真。此外,我想知道将 2 个输入转换为 int 的简单行是否合适。最后,在 python 代码中,“再见!”由于强制应用程序关闭的 EOF (control+z) 方法,从不运行。有一些怪癖,总的来说,我对 python 所需的代码更少感到满意。

额外:如果您查看最后打印语句中的代码,这是将 var 和字符串一起打印的好方法吗?

欢迎任何简单的技巧/提示。

C++

#include <iostream>

using namespace std;

double hmean(double a, double b);  //the harmonic mean of 2 numbers is defined as the invese of the average of the inverses.

int main()
{
    double x, y, z;
    cout << "Enter two numbers: ";

    while (cin >> x >> y)
    {
        try     //start of try block
        {
            z = hmean(x, y);
        }           //end of try block
        catch (const char * s)      //start of exception handler; char * s means that this handler matches a thrown exception that is a string
        {
            cout << s << endl;
            cout << "Enter a new pair of numbers: ";
            continue;       //skips the next statements in this while loop and asks for input again; jumps back to beginning again
        }                                       //end of handler
        cout << "Harmonic mean of " << x << " and " << y
            << " is " << z << endl;
        cout << "Enter next set of numbers <q to quit>: ";
    }
    cout << "Bye!\n";

    system("PAUSE");
    return 0;
}

double hmean(double a, double b)
{
    if (a == -b)
        throw "bad hmean() arguments: a = -b not allowed";
    return 2.0 * a * b / (a + b);
}

Python

class MyError(Exception):   #custom exception class
    pass

def hmean(a, b):
    if (a == -b):
        raise MyError("bad hmean() arguments: a = -b not allowed")  #raise similar to throw in C++?
    return 2 * a * b / (a + b);

print "Enter two numbers: "

while True:
    try:
        x, y = raw_input('> ').split() #enter a space between the 2 numbers; this is what .split() allows.
        x, y = int(x), int(y)   #convert string to int
        z = hmean(x, y)
    except MyError as error:
        print error
        print "Enter a new pair of numbers: "
        continue

    print "Harmonic mean of", x, 'and', y, 'is', z, #is this the most pythonic way using commas? 
    print "Enter next set of numbers <control + z to quit>: "   #force EOF

#print "Bye!" #not getting this far because of EOF

【问题讨论】:

    标签: c++ python input exception-handling


    【解决方案1】:

    对于函数hmean,我会尝试执行return语句,如果a等于-b,则引发异常:

    def hmean(a, b):
        try:
            return 2 * a * b / (a + b)
        except ZeroDivisionError:
            raise MyError, "bad hmean() arguments: a = -b not allowed"
    

    要在字符串中插入变量,format 方法是一种常见的替代方法:

    print "Harmonic mean of {} and {} is {}".format(x, y, z)
    

    最后,如果在将 x 或 y 转换为 int 时引发了 ValueError,您可能需要使用 except 块。

    【讨论】:

    • C++ 中的“raise”相当于“throw”吗?感谢您提供替代方法。已注明。
    • @klandshome 是的,我也建议你看看signal module 来处理按键事件。
    • 有没有一种类似于 C++ 的方式,其中 "q" 退出。不过,它可能涉及更多工作和另一个例外。我喜欢 C++ 方法中的 cin 对象。
    • 键入“q”会导致两个数字的提取失败,从而终止while(cin &gt;&gt; ..) 循环。在 Python 中,您读取一行然后解析它。解析代码会在失败时引发异常,因此有等价的。换句话说,您将需要两个 try-except 块,一个处理非数字输入或 EOF 的外部块和一个处理无效输入值的内部块。顺便说一句:在 C++ 中,抛出普通指针通常不是一个好主意。相反,您应该使用std::runtime_error,它也可以携带一个字符串作为上下文信息。
    【解决方案2】:

    这是一段我想抛给你的代码。类似的事情在 C++ 中是不容易实现的,但是通过分离关注点,它在 Python 中让事情变得更加清晰:

    # so-called "generator" function
    def read_two_numbers():
        """parse lines of user input into pairs of two numbers"""
        try:
            l = raw_input()
            x, y = l.split()
            yield float(x), float(y)
        except Exception:
            pass
    
    for x, y in read_two_numbers():
        print('input = {}, {}'.format(x, y))
    print('done.')
    

    它使用所谓的生成器函数,只处理输入解析以将输入与计算分开。这不是您要求的“尽可能接近”,而是“以pythonic方式”,但我希望您仍然会发现这很有用。另外,我冒昧地使用浮点数而不是整数来表示数字。

    还有一件事:升级到 Python 3,版本 2 不再开发,只是接收错误修正。如果您不依赖任何仅适用于 Python 2 的库,那么您应该不会感到太大的不同。

    【讨论】:

    • 这是深入的。感谢您的努力,因为我将研究您的代码。到目前为止,我有点倾向于使用 python 2.7,因为它对 Django 框架有最好的支持。如果我错了,请纠正我。
    • 注意浮动的使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    • 1970-01-01
    • 2012-09-15
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    相关资源
    最近更新 更多