在Python 3中修改txt文件

时间:2013-12-08 01:11:34

标签: python file-io python-3.x containers

我正在制作一个学校项目来制作视频俱乐部管理计划,我需要一些帮助。这是我想要做的: 我有一个包含客户端数据的txt文件,其中包含:

clientId:clientFirstName:clientLastName:clientPhoneNumber

:是数据中任何文件的分隔符。

在电影标题数据文件中,我得到了这个:

movieid:movieKindFlag:MovieName:MovieAvalaible:MovieRented:CopieInTotal

它的位置是在rentedData文件中应该有:

idClient:IdMovie:DateOfReturn

我能够做到这一点。我因缺乏经验而失败的地方: 我需要为电影数据文件制作一个有3个级别的容器,因为我想跟踪可用和租用的数字(当我租一部电影时以及当我退回电影时更改它们)。

第一级表示整个文件,调用它将打印整个文件,第二级应该在容器中有每一行,第三级是容器中每行的每个单词。

这是我的意思的一个例子:

dataMovie = [[[movie id],[movie title],[MovieAvailable],[MovieRented],[CopieInTotal]],[[movie id],[movie title],[MovieAvailable],[MovieRented],[CopieInTotal]]

我实际上知道我可以这样做两层:

DataMovie=[]
    MovieInfo = open('Data_Movie', 'r')
    #Reading the file and putting it into a container
    for ligne in MovieInfo:
        print(ligne, end='')
        words = ligne.split(":")
        DataMovie.append(words)
    print(DataMovie)

    MovieInfo.close()

它将所有单词分隔为:

[[MovieID],[MovieTitle],[movie id],[movie title],[MovieAvailable],[MovieRented],[CopieInTotal], [MovieID],[MovieTitle],[movie id],[movie title],[MovieAvailable],[MovieRented],[CopieInTotal]]

每一行都在同一个容器中(第二层),但这些行没有分开,不是很有帮助,因为我需要更改有关可用数量的特定信息,而租用的那些不能租用电影,如果全部这些副本都是租来的。

4 个答案:

答案 0 :(得分:0)

我认为您应该使用词典存储数据。而不是仅仅将列表嵌入彼此之中。

这是一个关于词典的快速页面。 http://www.network-theory.co.uk/docs/pytut/Dictionaries.html

所以你的数据可能看起来像

movieDictionary = {"movie_id":234234,"movie title":"Iron
   Man","MovieAvailable":Yes,"MovieRented":No,"CopieInTotal":20}

然后当你想要检索一个值时。

movieDictionary["movie_id"]

会产生价值。

234234

您还可以在字典值中嵌入列表。

这有助于回答您的问题吗?

答案 1 :(得分:0)

如果必须使用txt文件,以xml格式存储它可能会使任务更容易。因为已经为python提供了几个很好的xml解析器。

例如ElementTree

你可以像这样构建你的数据:

<?xml version="1.0"?>
<movies>
<movie id = "1">
    <type>movieKind</type>
    <name>firstmovie</name>
    <MovieAvalaible>True</MovieAvalaible>
    <MovieRented>False</MovieRented>
    <CopieInTotal>2</CopieInTotal>
</movie>
<movie id = "2">
    <type>movieKind</type>
    <name>firstmovie2</name>
    <MovieAvalaible>True</MovieAvalaible>
    <MovieRented>False</MovieRented>
    <CopieInTotal>3</CopieInTotal>
</movie>
</movies>

然后像这样访问和修改它:

import xml.etree.ElementTree as ET

tree = ET.parse('data.xml')
root = tree.getroot()

search = root.findall('.//movie[@id="2"]')
for element in search:
    rented = element.find('MovieRented')
    rented.text = "False"

tree.write('data.xml')

答案 2 :(得分:0)

您实际在做的是创建三个数据库:

  • 一个为客户
  • 一部电影
  • 一个出租

使用每行一个记录和:分隔符读取文本文件的相对简单方法是创建csv.reader对象。为了将数据库存储到您的程序中,我建议为客户端和租赁使用collections.namedtuple个对象列表。

from collections import namedtuple
from csv import reader

Rental = namedtuple('Rental', ['client', 'movie', 'returndate'])
with open('rentals.txt', newline='') as rentalsfile:
    rentalsreader = csv.reader(rentalsfile, delimiter=':')
    rentals = [Rental(int(row[0]), int(row[1]), row[2]) for row in rentalsreader]

电影词典列表:

with open('movies.txt', 'rb', newline='') as moviesfile:
    moviesreader = csv.reader(moviesfile, delimiter=':')
    movies = [{'id': int(row[0]), 'kind', row[1], 'name': row[2],
              'rented': int(row[3]), 'total': int(row[4])}  for row in moviesreader]

使用电影词典列表的主要原因是命名元组是一个元组,因此是不可变的,并且可能您希望能够更改rented

参考您对Daniel Rasmuson的回答的评论,因为您只将字段的放在文本文件中,您必须以某种方式将字段的名称硬编入您的程序

另一种解决方案是将日期存储在json个文件中。这些很容易映射到Python数据结构。

答案 3 :(得分:0)

这可能就是我们要找的东西

#Using OrderedDict so we always get the items in the right order when iteration. 
#So the values match up with the categories\headers
from collections import OrderedDict as Odict

class DataContainer(object):

    def __init__(self, fileName):
        '''
        Loading the text file in a list. First line assumed a header line and is used to set dictionary keys 
        Using OrderedDict to fix the order or iteration for dict, so values match up with the headers again when called
        '''
        self.file = fileName
        self.data = []
        with open(self.file, 'r') as content:
            self.header = content.next().split('\n')[0].split(':')
            for line in content:
                words = line.split('\n')[0].split(':')
                self.data.append(Odict(zip(self.header, words)))

    def __call__(self):
        '''Outputs the contents as a string that can be written back to the file'''
        lines = []
        lines.append(':'.join(self.header))
        for i in self.data:
            this_line = ':'.join(i.values())
            lines.append(this_line)
        newContent = '\n'.join(lines)
        return newContent

    def __getitem__(self, index):
        '''Allows index access self[index]'''
        return self.data[index]

    def __setitem__(self, index, value):
        '''Allows editing of values self[index]'''
        self.data[index] = value

d = DataContainer('data.txt')
d[0]['MovieAvalaible'] = 'newValue'  # Example of how to set the values

#Will print out a string with the contents
print d()