如何处理来自raw_input的整数和字符串?

3 投票
5 回答
11055 浏览
提问于 2025-04-17 10:50

我还在努力理解Python。它和PHP差别太大了。

我把选项设置成了整数,但我的菜单里需要用字母。

我该怎么把整数和字符串一起使用呢?
为什么我不能先设置成字符串再设置成整数呢?

def main(): # Display the main menu
    while True:
        print
        print "  Draw a Shape"
        print "  ============"
        print
        print "  1 - Draw a triangle"
        print "  2 - Draw a square"
        print "  3 - Draw a rectangle"
        print "  4 - Draw a pentagon"
        print "  5 - Draw a hexagon"
        print "  6 - Draw an octagon"
        print "  7 - Draw a circle"
        print
        print "  D - Display what was drawn"
        print "  X - Exit"
        print

        choice = raw_input('  Enter your choice: ')

        if (choice == 'x') or (choice == 'X'):
            break

        elif (choice == 'd') or (choice == 'D'):
            log.show_log()

        try:
            choice = int(choice)
            if (1 <= choice <= 7):

                my_shape_num = h_m.how_many()
                if ( my_shape_num is None): 
                    continue

                # draw in the middle of screen if there is 1 shape to draw
                if (my_shape_num == 1):
                    d_s.start_point(0, 0)
                else:
                    d_s.start_point()
                #
                if choice == 1: 
                    d_s.draw_triangle(my_shape_num) 
                elif choice == 2: 
                    d_s.draw_square(my_shape_num) 
                elif choice == 3:             
                    d_s.draw_rectangle(my_shape_num) 
                elif choice == 4:             
                    d_s.draw_pentagon(my_shape_num) 
                elif choice == 5:             
                    d_s.draw_hexagon(my_shape_num) 
                elif choice == 6:             
                    d_s.draw_octagon(my_shape_num) 
                elif choice == 7: 
                    d_s.draw_circle(my_shape_num)

                d_s.t.end_fill() # shape fill color --draw_shape.py-- def start_point

            else:
                print
                print '  Number must be from 1 to 7!'
                print

        except ValueError:
            print
            print '  Try again'
            print

5 个回答

2

我觉得你的代码可以简化一下:

def main():
    while 1:
        print
        print "  Draw a Shape"
        print "  ============"
        print
        print "  1 - Draw a triangle"
        print "  2 - Draw a square"
        print "  3 - Draw a rectangle"
        print "  4 - Draw a pentagon"
        print "  5 - Draw a hexagon"
        print "  6 - Draw an octagon"
        print "  7 - Draw a circle"
        print
        print "  D - Display what was drawn"
        print "  X - Exit"
        print
        choice = raw_input('  Enter your choice: ').strip().upper()
        if choice == 'X':
            break
        elif choice == 'D':
            log.show_log()
        elif choice in ('1', '2', '3', '4', '5', '6', '7'):
            my_shape_num = h_m.how_many()
            if my_shape_num is None:
                continue
            elif my_shape_num == 1:
                d_s.start_point(0, 0)
            else:
                d_s.start_point()
            if choice == '1':
                d_s.draw_triangle(my_shape_num)
            elif choice == '2':
                d_s.draw_square(my_shape_num)
            elif choice == '3':
                d_s.draw_rectangle(my_shape_num)
            elif choice == '4':
                d_s.draw_pentagon(my_shape_num)
            elif choice == '5':
                d_s.draw_hexagon(my_shape_num)
            elif choice == '6':
                d_s.draw_octagon(my_shape_num)
            elif choice == '7':
                d_s.draw_circle(my_shape_num)
            d_s.t.end_fill()
        else:
            print
            print '  Invalid choice: ' + choice
            print
2

我不太明白你在问什么。raw_input() 这个函数总是返回一个 str 类型的结果。如果你想让用户输入的内容自动转换成 int 或其他简单类型,可以使用 input() 这个函数,它可以做到这一点。

你选择让用户输入字母或数字,其实你也可以把菜单中的“字母”选项分配给数字。或者,你可以更好地利用 try/except 这个功能,比如:

try:
    choice = int(user_input)
    if choice == 1:
        # do something
    elif ...
except ValueError: # type(user_input) != int
    if choice == 'X' or choice == 'x':
        # do something
    elif ...
    else:
        print 'no idea what you want' # or print menu again
6

让我用另一个问题来回答你的问题:
真的有必要把字母和数字混在一起吗?
难道它们不能都是字符串吗?

好吧,我们慢慢来,看看程序在做什么:

  1. 显示主菜单
  2. 询问/接收用户输入
    • 如果有效:好的
    • 如果无效:打印错误信息并重复
  3. 现在我们有了有效的输入
    • 如果是字母:执行特殊任务
    • 如果是数字:调用正确的绘图函数

第一点。 我们为此做一个函数:

def display_menu():
    menu_text = """\
  Draw a Shape
  ============

  1 - Draw a triangle
  2 - Draw a square
  D - Display what was drawn
  X - Exit"""
    print menu_text

display_menu 非常简单,所以不需要解释它的作用,但我们稍后会看到把这段代码放到一个单独的函数中的好处。

第二点。 这将通过一个循环来完成:

options = ['1', '2', 'D', 'X']

while 1:
    choice = raw_input('  Enter your choice: ')
    if choice in options:
        break
    else:
        print 'Try Again!'

第三点。 嗯,经过再三考虑,也许这些特殊任务并没有那么特殊,所以我们也把它们放到一个函数里:

def exit():
    """Exit"""  # this is a docstring we'll use it later
    return 0

def display_drawn():
    """Display what was drawn"""
    print 'display what was drawn'

def draw_triangle():
    """Draw a triangle"""
    print 'triangle'

def draw_square():
    """Draw a square"""
    print 'square'

现在我们把所有内容放在一起:

def main():
    options = {'1': draw_triangle,
               '2': draw_square,
               'D': display_drawn,
               'X': exit}

    display_menu()
    while 1:
        choice = raw_input('  Enter your choice: ').upper()
        if choice in options:
            break
        else:
            print 'Try Again!'

    action = options[choice]   # here we get the right function
    action()     # here we call that function

你切换的关键在于 options,现在它不再是一个 list 而是一个 dict,所以如果你简单地像 if choice in options 这样迭代,你的迭代是在 上:['1', '2', 'D', 'X'],但是如果你做 options['X'],你就得到了退出函数(这不是很棒吗!)。

现在我们再来改进一下,因为维护主菜单信息和 options 字典并不是很好,一年后我可能会忘记更改其中一个,我得不到我想要的,而且我懒,不想做两次同样的事情,等等...
那么为什么不把 options 字典传递给 display_menu,让 display_menu 使用 __doc__ 中的文档字符串来生成菜单呢:

def display_menu(opt):
    header = """\
  Draw a Shape
  ============

"""
    menu = '\n'.join('{} - {}'.format(k,func.__doc__) for k,func in opt.items())
    print header + menu

我们需要 OrderedDict 而不是 dict 来作为 options,因为 OrderedDict 顾名思义会保持其项目的顺序(可以查看 官方文档)。所以我们有:

def main():
    options = OrderedDict((('1', draw_triangle),
                           ('2', draw_square),
                           ('D', display_drawn),
                           ('X', exit)))

    display_menu(options)
    while 1:
        choice = raw_input('  Enter your choice: ').upper()
        if choice in options:
            break
        else:
            print 'Try Again!'

    action = options[choice]
    action()

请注意,你必须设计你的操作,使它们都有相同的签名(它们本来就应该是这样的,它们都是操作!)。你可能想使用可调用对象作为操作:实现了 __call__ 的类实例。在这里创建一个基础的 Action 类并从中继承将是完美的选择。

撰写回答