Objects for words in a Python flashcard program
我正在制作一个flashcard程序,在该程序中,我获取一个包含几个列的文本文件,如英语单词、法语等价物、性别、单词类型等。我的想法是创建一个循环,读取文本文件的每一行,用制表符分隔,并为每一行创建一个用户定义的单词对象实例。
在下面的代码块中,我导入文本文件,将其处理到列表中,然后尝试创建以前定义的对象的实例:word。我希望该对象在列表中的第二个项目中包含它的名称,以便可以轻松搜索,但它不允许我这样做,请有人帮助我处理代码:
1 2 3 4 5 6 | file = (open('dictionary.txt', 'r')).readline() import re line_list = re.split(r'\t', file.rstrip(' ')) line_list[1] = Word(line_list[0], line_list[1], line_list[2], line_list[3]) |
创建一个
1 2 3 4 5 6 7 | import re instance_dict = {} with open('dictionary.txt') as f: for line in f: line_list = re.split(r'\t', line.rstrip(' ')) instance_dict[line_list[1]] = Word(*line_list[:4]) |
为什么是
It is good practice to use the
with keyword when dealing with file
objects. This has the advantage that the file is properly closed after
its suite finishes, even if an exception is raised on the way.
号
您还可以使用
1 2 3 4 5 6 | import csv instances = {} with open('dictionary.txt', 'rb') as f: reader = csv.reader(f, delimiter='\t') instances = {line[1]: Word(*line) for line in reader} |
号
你可能有一个适当的解决方案,这取决于对你的要求的澄清。
"My idea was to create a loop that read each line of the text file,
separating by tabs, and"
号
如果文本文件已经过预验证或可靠,可以忽略错误处理(例如,没有用单个选项卡均匀分隔)。
1 2 3 4 5 | with open('dictionary.txt', 'r') as f: [line.strip().split("\t") for line in f.read().split(" ") if line.strip()] |
将获得创建Word对象实例所需的(综合)列表,而不使用re
"then attempt to create an instance of a previously defined object:
Word."
号
1 2 3 4 5 | with open('dictionary.txt', 'r') as f: [Word(line.strip().split("\t")) for line in f.read().split(" ") if line.strip()] |
。
"I would like the object to have the second item on the list for it's
name so that it is easily searchable,"
号
你能用一个例子来重写这个吗?
but it's not letting me do this,
号
1 | line_list[1] = Word(line_list[0], line_list[1], line_list[2], line_list[3]) |
。
抱歉,我把你弄到这里了,为什么要用line_list[1]来引用新创建的单词实例,其中line_list[1]本身就是一个参数?
有了你的澄清,我想要像这样的东西返工代码:
1 | from pprint import pprint |
我对你的阶级定义的假设是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | class Word(): def __init__(self, **kwargs): self.set_attrs(**kwargs) def __call__(self): return self.get_attr("swedish_word") def set_attrs(self, **kwargs): for k, v in kwargs.iteritems(): setattr(self, k, v) def get_attr(self, attr): return getattr(self, attr) def get_attrs(self): return ({attr.upper():getattr(self, attr) for attr in self.__dict__.keys()}) def print_attrs(self): pprint(self.get_attrs()) if __name__ == '__main__': # sample entries in dictionary.txt # swedish_word english_word article word_type # hund dog ett noun # katt cat ett noun # sova sleep ett verb with open('dictionary.txt', 'r') as f: header = f.readline().strip().split("\t") instances = [Word(**dict(zip(header, line.strip().split("\t")))) for line in f.read().split(" ") if line.strip()] # for line in f.read().split(" "): # data = dict(zip(header, line.strip().split("\t"))) # w = Word(**data) |
。
您可以获取这样一个给定的瑞典单词的实例属性
1 2 3 4 5 6 7 | def print_swedish_word_properties(swedish_word): for instance in instances: if instance() == swedish_word: print"Properties for Swedish Word:", swedish_word instance.print_attrs() print_swedish_word_properties("hund") |
有这样的输出
1 2 3 4 5 | Properties for Swedish Word: hund {'ARTICLE': 'ett', 'ENGLISH_WORD': 'dog', 'SWEDISH_WORD': 'hund', 'WORD_TYPE': 'noun'} |
。
或者可以使用任何其他类方法来搜索不同属性上的实例
首先,最好使用with,as语句从文件中获取输入,因为关闭过程是自动处理的。其次,要从文件中读取所有行,必须使用read lines()而不是readline()。尝试如下操作:
1 2 3 4 5 6 | with open('dictionary.txt','r') as file : line_list = file.readlines() splitLineList = [] for lines in line_list : splitLineList.append(re.split(r'\t',lines.strip(' ')) |
。
这是一个使用名称双重的更清洁的解决方案。最后你将得到一个名为"单词"的dict,用于按名称查找每个单词。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/usr/bin/env python # -*- coding: utf-8 -*- import pprint from collections import namedtuple Word = namedtuple('Word', ['name', 'french', 'gender', 'type_']) words = {} with open('dictionary.txt', 'rU') as fin: for word in (Word(*r.rstrip(' ').split('\t')) for r in fin): words[word.name] = word pprint.pprint(words) |