如何正确创建 returns 从 python 中的文件生成的列表的列表子类?
How to properly create a list subclass that returns a list generated from file in python?
我 运行 遇到一些子 classing 问题。
我需要创建一个继承列表属性的 class 但我需要 returned 列表 (self.tiles_pool) 是一个在构造 class 时创建。该列表由外部 CSV 文件生成。我尝试在没有继承的情况下创建 class,但很快意识到如果不创建单独的方法就无法 return 我的列表。但是我需要 class 的实例是一个列表对象(即在我打印对象时打印生成的列表)。 class 用于创建拼贴池,例如拼字游戏中的字母拼贴袋。
如果有某种方法 returning 我的列表 (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)
我知道这个实现可能看起来很奇怪,我可能只是把它放在一个函数中,但我正在按照指示将它变成 class。任何帮助或建议将不胜感激。谢谢
如果您不使用它,为什么要子类化 list
? self
就是你想要的列表,不需要再创建tiles_pool
。由于列表可以用序列初始化,延迟父 __init__
直到你可以将 csv 提供给它。你的代码做了一些我不明白的事情,比如复制图块 line[2]
次,但我想你知道你在那里做什么。
在此示例中,我删除了 tiles_pool
以支持使用 self
并进行了一些其他调整,例如使用列表的 "truthiness"(bool([1]) is True
而 bool([]) 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()
如果您想避免继承和用户定义的方法,我会利用 python 的 magic 方法来实现。
我 运行 遇到一些子 classing 问题。
我需要创建一个继承列表属性的 class 但我需要 returned 列表 (self.tiles_pool) 是一个在构造 class 时创建。该列表由外部 CSV 文件生成。我尝试在没有继承的情况下创建 class,但很快意识到如果不创建单独的方法就无法 return 我的列表。但是我需要 class 的实例是一个列表对象(即在我打印对象时打印生成的列表)。 class 用于创建拼贴池,例如拼字游戏中的字母拼贴袋。
如果有某种方法 returning 我的列表 (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)
我知道这个实现可能看起来很奇怪,我可能只是把它放在一个函数中,但我正在按照指示将它变成 class。任何帮助或建议将不胜感激。谢谢
如果您不使用它,为什么要子类化 list
? self
就是你想要的列表,不需要再创建tiles_pool
。由于列表可以用序列初始化,延迟父 __init__
直到你可以将 csv 提供给它。你的代码做了一些我不明白的事情,比如复制图块 line[2]
次,但我想你知道你在那里做什么。
在此示例中,我删除了 tiles_pool
以支持使用 self
并进行了一些其他调整,例如使用列表的 "truthiness"(bool([1]) is True
而 bool([]) 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()
如果您想避免继承和用户定义的方法,我会利用 python 的 magic 方法来实现。