如何正确创建一个列表子类,返回从python中的文件生成的列表?

时间:2016-03-13 04:49:13

标签: python list inheritance return subclassing

我遇到了子类化的一些问题。

我需要创建一个继承列表属性的类,但我需要返回的列表( self.tiles_pool )是在构造类时创建的列表。该列表由外部CSV文件生成。我尝试创建没有继承的类,但很快意识到没有创建单独的方法就无法返回我的列表。但是我需要将类的实例作为列表对象(即在打印对象时打印生成的列表)。这个类用于创建一个Tile Pool,就像拼字游戏中的一堆字母拼贴一样。

如果有某种方法可以返回我的列表( self.tiles_pool 没有继承而不使用用户定义的方法那会更好。

到目前为止,这是我的代码:

import csv
import random


class TilePool(list):
    def __init__(self):
        list.__init__(self)

        # Open csv file
        with open("tiles.csv") as f:
            # Read csv into list of lists of each lines values
            tiles_csv = csv.reader(f, delimiter=",")

            # Convert the list into a tile pool
            self.tiles_pool = [(line[0], line[1])
                               for line in tiles_csv if len(line[0]) == 1
                               for x in xrange(int(line[2]))]

            del tiles_csv

    def pop(self, tile_count=None):
        assert len(self.tiles_pool) > 0, "# Tile Pool is empty"

        if tile_count is None:
            tile_count = 7

        assert tile_count in xrange(1, 8), "# Tile Count must be between 1 and 7"

        new_tiles = []
        counter = 1
        while len(self.tiles_pool) > 0 and counter <= tile_count:
            rand_choice = random.choice(self.tiles_pool)  # Get a random tile
            new_tiles.append(rand_choice)  # Add it to new_tiles list
            self.tiles_pool.remove(rand_choice)  # Delete it from pool

            counter += 1

        return new_tiles

    def view_pool(self):
        if len(self.tiles_pool) == 0:
            print("# Tile Pool is empty")

        else:
            for tile in self.tiles_pool:
                print("{letter}: {score}".format(letter=tile[0], score=tile[1]))

            print len(self.tiles_pool)

我知道这个实现可能看起来很奇怪,我可能只是将它放在一个函数中,但我正在指导它使它成为一个类。任何帮助或建议将不胜感激。感谢。

2 个答案:

答案 0 :(得分:0)

如果您不使用它,为什么要继承listself是您想要的列表,无需创建tiles_pool。由于列表可以使用序列进行初始化,因此可以延迟父__init__,直到您可以将其提供给csv。你的代码做了一些我不理解的事情,比如复制tile line[2]次,但我知道你在那里做了什么。

在此示例中,我删除了tiles_pool,转而使用self并进行了一些其他调整,例如使用列表的“真实性”(bool([1]) is Truebool([]) is False)而不是使用len,但它应该与原始版本相同。

import csv
import random


class TilePool(list):
    def __init__(self):
        with open("tiles.csv") as f:
            tiles_csv = csv.reader(f, delimiter=",")
            list.__init__(self, (line[0:2]
                           for line in tiles_csv if len(line[0]) == 1
                           for x in xrange(int(line[2]))))


    def pop(self, tile_count=None):
        # non-empty list is truthy
        assert self, "# Tile Pool is empty"

        if tile_count is None:
            tile_count = 7

        assert tile_count in range(1, 8), "# Tile Count must be between 1 and 7"

        new_tiles = []
        counter = 1
        while self and counter <= tile_count:
            rand_choice = random.choice(self)  # Get a random tile
            new_tiles.append(rand_choice)  # Add it to new_tiles list
            self.remove(rand_choice)  # Delete it from pool
            counter += 1
        return new_tiles

    def view_pool(self):
        if not self:
            print("# Tile Pool is empty")
        else:
            for tile in self:
                print("{letter}: {score}".format(letter=tile[0], score=tile[1]))
            print len(self)

t = TilePool()
t.pop(3)
t.view_pool()

答案 1 :(得分:0)

如果你想避免继承和用户定义的方法,我会利用python的magic方法来做到这一点。