简体   繁体   English

使用原始输入给定的名称添加新字典(Python 2.7)

[英]Add new dictionary with the name given by raw input (Python 2.7)

I just finished a Python course and I'm working on my very first project, a tool for practising Spanish verbs and their conjugations. 我刚刚完成了Python课程,并且正在从事我的第一个项目,这是一个用于练习西班牙语动词及其词缀的工具。 The tool is working, but now I want to improve it. 该工具正在运行,但现在我想对其进行改进。 For example, it's currently difficult to handle the data (eg add past tense to a verb + complicated random quiz function). 例如,当前难以处理数据(例如,将过去式添加到动词中+复杂的随机测验函数)。

I however stumbled upon a couple of problems, one of them being: how can I add a new dictionary and give that dictionary the name from raw input? 但是,我偶然发现了两个问题,其中一个是: 如何添加新字典并为原始输入的字典命名? I thought that shouldn't be hard, but haven't found a solution after a lot of searching. 我认为应该不难,但经过大量搜索后仍未找到解决方案。

I have two files: one with the code and a .txt file that contains all verbs as dictionaries on seperate lines. 我有两个文件:一个带有代码,一个.txt文件,其中包含所有动词作为单独行上的词典。 Below you see my function for adding a new verb and appending it to the .txt file. 在下面,您会看到我的功能,用于添加新动词并将其附加到.txt文件。

Example of a line in my .txt file: .txt文件中的一行示例:

to talk = {'present': ['hablo', 'hablas', ... ]}

Current code: 当前代码:

def add_verb():
    verb = {}
    name = (raw_input("Verb in Dutch: "))
    tense = (raw_input("Verb tense: ")) 

    conjugations = []
    conjugations.append(raw_input("Yo: "))
    conjugations.append(raw_input("Tú: "))

    verb_dict[tense] = conjugations

    with open("verbs.txt", "a") as abc:
        abc.write("%s = {'%s': %s}\n" % (name, tense, conjugations))

Basically, what I want is this: 基本上,我想要的是:

abc.write(dictionary)

Thus, I want the dictionary to be written into the file as it is, but with the name of the dictionary given by raw input. 因此,我希望将字典按原样写入文件,但使用原始输入给出的字典名称。

I'm currently also thinking of using a Verb class, because I think that would make the tool even better, but then I stumbled upon the exact same problem (how do I give a new class instance a name that's given by raw input?). 我目前也正在考虑使用Verb类,因为我认为这会使工具变得更好,但是随后我偶然发现了完全相同的问题(如何给新的类实例一个由原始输入给出的名称?) 。

PS If you see other things that I should improve, please don't hesitate to mention this. PS:如果您看到我需要改进的其他地方,请不要犹豫。

From the other context in your question, it sounds like you might actually benefit from a nested dictionary structure more similar to this: 从问题中的其他上下文来看,听起来您实际上可能会从类似于以下内容的嵌套字典结构中受益:

import pprint

spanish_dictionary = {"hablar": {"present": ["hablo", "hablas", "hablamos", ...],
                                 "past": ["i'm", "out", "of", "my", "depth"]},
                      "comer": {"present": ["como", ...] #you get the idea
                                }
                     }

def add_verb():
    spanish_dictionary["tener"] = {"present": ["tengo", ...]}

add_verb()

pprint.pprint(spanish_dictionary)

Note that it will run in Python2 if you replace the ellipses with something appropriate, and it actually already already runs in Python3, giving the output: 请注意,如果将椭圆替换为适当的东西,它将在Python2中运行,并且它实际上已经在Python3中运行,给出输出:

{'comer': {'present': ['como', Ellipsis]},
 'hablar': {'past': ["i'm", 'out', 'of', 'my', 'depth'],
            'present': ['hablo', 'hablas', 'hablamos', Ellipsis]},
 'tener': {'present': ['tengo', Ellipsis]}}

Please forgive my very limited Spanish, hopefully this is enough to demonstrate the structure. 请原谅我非常有限的西班牙语,希望这足以说明其结构。 As you can see, it's generally a good idea not to have dictionaries with names you want to change, but instead to just put these in a bigger dictionary, so rather than having to do anything difficult and dangerous with exec , you can add dictionaries by adding values to the larger dictionary. 如您所见,通常不建议使用要更改名称的字典,而只是将它们放在更大的字典中,这样,不必用exec做任何困难和危险的事情,您可以通过以下方式添加字典:将值添加到较大的字典中。 If you have a name given by raw_input , say, like so: 如果您有raw_input给定的名称,请说,像这样:

new_verb_name = raw_input()
new_verb_data = some_processing(raw_input())
spanish_dictionary[new_verb_name] = new_verb_data

Regarding your idea to have a Verb class - I think this is probably a very good idea, but I have a tip. 关于您开设动词课程的想法-我认为这可能是一个很好的想法,但我有一个建议。 A Verb will probably be immutable, as the conjugations of a verb don't change, so collections.namedtuple seems suited to this task. 动词可能是不可变的,因为动词的变位不会改变,因此collections.namedtuple似乎适合此任务。 namedtuple allows you to basically define a class without the hassle of defining it if all it needs to do is store values. namedtuple允许您从根本上定义一个类,而无需麻烦地定义它(如果它需要做的就是存储值)。 Note that namedtuple is actually a factory function that returns a class. 请注意, namedtuple实际上是一个返回类的工厂函数。 You might use it like so: 您可以这样使用它:

from collections import namedtuple

Verb = namedtuple("Verb", "past present")
Conjugation = namedtuple("Conjugation", "yo tu")

spanish_dict = {"hablar": Verb(present=Conjugation(yo="hablo", tu="hablas"),
                               past=Conjugation(yo="yo hablo in past :p", tu=...))
               }

print(spanish_dict)
print(spanish_dict["hablar"].present.tu)

This has the output: 输出如下:

{'hablar': Verb(past=Conjugation(yo='yo hablo in past :p', tu=Ellipsis), present=Conjugation(yo='hablo', tu='hablas'))}
hablas

As you can see, it's pretty expressive to be able to use .present.tu to access the attributes of the verb. 如您所见,能够使用.present.tu访问动词的属性非常有表现力。 This is just an example though - you'll get to do the actual job of all the Spanish : ) 不过,这只是一个例子-您将完成所有西班牙语的实际工作:)

It can be fun to see what the line 看到什么线可能很有趣

Verb = namedtuple("Verb", "past present")

would be equivalent to in a full class definition. 等同于完整的类定义。 You can view it by running 您可以通过运行查看

Verb = namedtuple("Verb", "past present", verbose=True)

Bewarned, this results in 50 odd lines of code. 警告,这将导致50行奇数行代码。 To be honest, whoever implemented namedtuple is probably just showing off a bit ;). 说实话,实施了namedtuple的人可能只是在炫耀一下;)。 But this does illustrate how powerful the namedtuple factory is. 但这确实说明了namedtuple工厂的功能。

What you are trying to do is really not recommended, because it mixes data (your user input) and code, which is usually the sign of some design flaw. 确实不建议您尝试执行操作,因为它会混合数据(您的用户输入)和代码,这通常是某些设计缺陷的标志。

But, for the record, you can achieve what you want using exec : 但是,记录下来,您可以使用exec

>>> name = input("What is your name?\n")
What is your name?
test

>>> exec(f"{name} = dict()")  # Python 3.6 and above
>>> exec("{0} = dict()".format(name))  # Python 2.7 & 3.5
>>> print(test)
{}

Warning 警告

exec simply executes the code it gets as an argument. exec只是执行作为参数获取的代码。 As reminded by @Błażej Michalik in the comments, this is quite dangerous, especially combined with user's input. 正如@BłażejMichalik在评论中所提醒的那样,这非常危险,尤其是与用户输入结合使用时。

With my example, if the user decides to enter actual Python code instead of their name, it will get executed so it can cause great damages!!! 在我的示例中,如果用户决定输入实际的Python代码而不是其名称,它将被执行,因此可能造成巨大损失!!!


Why is it so bad to mix data and code and where to go from here? 为什么将数据和代码混合以及从何处去如此糟糕?

I mentioned that doing what you're trying to do is a common sign of design flaw. 我提到做您想做的事情是设计缺陷的常见标志。 The simple reason is that your code is not exposed to the outside and should not depend on actual data. 原因很简单,您的代码不会暴露在外部,也不应该依赖于实际数据。 Applied to your example: why should the name of a dictionary, which is an object living inside of your program only, depend on anything from "the outside world"? 以您的示例为例:为什么词典名称(仅存在于程序内部)仅依赖于“外界”中的任何内容?

So, here are some hints on how to proceed: 因此,以下是一些有关如何进行的提示:

  • store all your data in the JSON format (or YAML, TOML, XML, etc.). 以JSON格式(或YAML,TOML,XML等)存储所有数据。 You're not far from that already, given the way you store your data in the text file. 鉴于您将数据存储在文本文件中的方式,您距离这还不远。 It'll just make it more standard. 它只会使其更加标准。
  • if you use user input, store that input in a variable, which has any name you want. 如果使用用户输入,则将该输入存储在变量中,该变量具有所需的任何名称。 For instance, let's say you want the user to create some collection of words, just create a class WordsCollection , which will have a name attribute, and create instances of that class with any variable name you want. 例如,假设您希望用户创建一些单词集合,只需创建一个具有name属性的类WordsCollection ,然后使用所需的任何变量名创建该类的实例。
  • if you start learning Python, I would rather choose working with Python 3 :) 如果您开始学习Python,我宁愿选择使用Python 3 :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM