在Python中读取一系列输入/输出

在Python中读取一系列输入/输出,python,Python,对于我的应用程序,我需要打印出一系列输出,然后接受用户的输入。这样做的最佳方式是什么 比如: 像这样的,但至少会持续10次。我唯一关心的是这样做会弥补代码可读性差的缺点 我该怎么做?我是否应该创建如下函数: def printOut(string): print string field_defs = [ ('name', 'Name'), ('dob' , 'Date of Birth'), ('sex' , 'Gender'), #... ]

对于我的应用程序,我需要打印出一系列输出,然后接受用户的输入。这样做的最佳方式是什么

比如:

像这样的,但至少会持续10次。我唯一关心的是这样做会弥补代码可读性差的缺点

我该怎么做?我是否应该创建如下函数:

def printOut(string):
   print string
field_defs = [
    ('name', 'Name'),
    ('dob' , 'Date of Birth'),
    ('sex' , 'Gender'),
    #...
    ]

# Figure out the widest description.    
maxlen = max(len(descr) for (name, descr) in field_defs)

fields = {}
for (name, descr) in field_defs:
    # Pad to the widest description.
    print '%-*s:' % (maxlen, descr),
    fields[name] = raw_input()

# You should access the fields directly from the fields variable.
# But if you really want to access the fields as local variables...
locals().update(fields)

print name, dob, sex

或者有更好的方法吗?

如果您正在阅读多个字段,您可能希望执行以下操作:

def printOut(string):
   print string
field_defs = [
    ('name', 'Name'),
    ('dob' , 'Date of Birth'),
    ('sex' , 'Gender'),
    #...
    ]

# Figure out the widest description.    
maxlen = max(len(descr) for (name, descr) in field_defs)

fields = {}
for (name, descr) in field_defs:
    # Pad to the widest description.
    print '%-*s:' % (maxlen, descr),
    fields[name] = raw_input()

# You should access the fields directly from the fields variable.
# But if you really want to access the fields as local variables...
locals().update(fields)

print name, dob, sex
“10倍…代码可读性差”

不是真的。你必须提供比这更复杂的东西

20行代码几乎不是问题。您可以轻松地编写20多行代码,以避免只编写20行代码

您还应该阅读
原始输入的说明

它会写一个提示。你的四行代码真是太棒了

x = raw_input( '1' )
y = raw_input( '2' )

您不能再简化了。

第一个注意:
raw\u input()
接受一个可选参数。。。提示字符串

关于更广泛的问题,一种过于简单的方法是创建一个类,该类定义表单的元素,并为其输入、验证和以后的操作或输出提供函数

有了这样一个类,就可以创建(实例化)、收集、存储等实例

这种方法不需要比以下方法更复杂:

#!/usr/bin/python
# I use /usr/bin/env python; but making SO's syntax highlighter happy.

class generic_form:
    def __init__(self, element_list):
        self.form_elements = element_list
        self.contents= dict()

    def fill_it_in(self):
        for prompt in self.form_elements:
            self.contents[prompt] = raw_input(prompt)

    def get(self, item):
        return self.contents[item]

    def print_it(self):
        for each in self.form_elements:
            print each, self.contents[each]

if __name__ == '__main__':
    sample_fields = ("Given Name: ",
                     "Surname: ",
                     "Date of Birth: ",
                     "Notes: ")

    example = generic_form(sample_fields)

    print "Fill in my form:"
    example.fill_it_in()

    print
    print "Please review your input:"
    example.print_it()

    # store(:%s, %s: %s" % (example.get('Surname: '), \
    #    example.get('Given Name: '), example.get('Notes: '))
主代码只有十几行,用于定义带有输入的通用表单类 和输出功能(以及一个简单的
get()
方法,用于进一步说明)

本例的其余部分只是创建一个实例,并说明如何使用它

因为我的
generic\u表单
类是泛型的,所以我们必须提供一个要填写的字段名列表。这些名称用作字段的两个名称,以供以后访问(有关示例,请参见
get()
方法)。就我个人而言,我不会这样做,我会提供一个短字段名列表和类似于Marcelo示例的提示。然而,我希望这个特殊的例子尽可能简短,以便让大家了解要点

(顺便说一句,最后的注释是调用一个假想的“store()”函数来为后代存储该函数)

这是最简单的方法。但是,您会很快发现,拥有一个更丰富的类,对每个字段进行验证,以及以不同方式格式化和输出该字段实例的独立类,以及不同的输入类,这将非常有用。“teletype”输入(由Python
raw_input()
内置函数提供)是最粗糙的形式(主要用于简单性和使用shell重定向处理文件的能力)。还可以使用GNU
readline
支持(已经作为Python中的标准库提供)、curses支持(也包括在内)来支持输入,还可以想象编写一些HTML包装器和CGI代码来处理基于web的输入

如果我们需要或想要支持除“哑终端”以外的任何形式的输入或输出,那么将“
raw\u input()
”和“
print
”耦合到我们的类中将意味着更多的工作

如果我们创建一个只关心要收集的数据的类,那么它可以为任何其他输入类提供一个接口,以获取带有“
setter
”函数引用的提示列表(可能还有一个“必需”或“可选”标志)。然后任何输入类的任何实例都可以请求任何形式的所需/所需输入列表。。。显示提示,调用“
setter
”方法(返回布尔值以指示提供的数据是否有效),循环“必需”字段上的错误输入,提供跳过“可选”字段,等等

请注意,显示提示、接受响应、通过setter方法将这些提示中继回数据对象以及处理无效输入的逻辑对于许多类型的表单都是相同的。我们所需要的只是表单提供提示列表及其相应的验证函数的一种方式(我们需要确保所有这些验证函数具有相同的语义——采用相同的参数等等)

下面是一个将输入行为与数据字段的存储和验证分离的示例:

   #!/usr/bin/env python

    class generic_form:
        def __init__(self, element_list):
            self.hints = list()
            for each in element_list:
                self.hints.append((each, each, self.store))
            self.contents= dict()
        def store(self, key, data):
            '''Called by client instances
            '''
            self.contents[key] = data
            return True

        def get_hints(self):
            return self.hints

        def get(self, item):
            return self.contents[item]


    def form_input(form):
        for each, key, fn in form.get_hints():
            while True:
                if fn(key,raw_input(each)):
                    break
                else:
                    keep_trying = raw_input("Try again:")
                    if keep_trying.lower() in ['n', 'no', 'naw']:
                        break

    if __name__ == '__main__':
        sample_fields = ("Given Name: ",
                         "Surname: ",
                         "Date of Birth: ",
                         "etc: ")

        example = generic_form(sample_fields)

        print "Fill in my form:"
        form_input(example)

        print
        print "Please review your input:"
        for i, x, x in example.get_hints():
            print example.get(i),
在这种情况下,额外的复杂性是没有做任何有用的事情。我们的通用表单不执行验证。但是,这个相同的输入函数可以用于提供相同接口的任何数据/表单类。在本例中,该接口只需要提供“提示字符串”、存储键和存储函数引用元组的
get_-hints()
方法,以及必须返回“True”或“False”并为要存储的键和数据获取参数的
store()
方法

我们的存储密钥作为不透明项传递给输入“客户机”,必须通过调用
store()
方法传回,这一事实有点微妙;但它允许我们对多个表单元素使用任何单个验证函数。。。所有名称可以是任何字符串,所有日期都必须传递一些调用到
time.strftime()
或某个第三方解析器。。。等等

主要的一点是,我可以创建更好的表单类,这些表单类根据收集和存储的数据实现适当的数据验证方法。输入示例将适用于我们最初的哑表单,但它将更好地适用于从调用
store()
返回有意义结果的表单(表单和输入处理之间更好的接口可能会提供“错误”和“帮助”提示,以及我们在此处显示的简单简短的“输入”提示。更复杂的系统可能会通过通过
get_hints()
方法“datum”对象。这需要forms类实例化此类对象并存储列表