我有类似的东西,硬编码:
class csv_row:
def __init__(self, name, time, more_stuff):
self.name = name
self.time = time
self.more_stuff = more_stuff
此类是csv行的表示形式。我想要做的是使它更通用,并抓住csv文件的头部并使用它以与此列表相同的方式初始化它。像这样:
class csv_row:
def __init__(self, list_of_attrs):
for column in list_of_attrs:
# initialize a self.variable with the same name as the column
例如,csv的标头是[name, time, something]
。 __init__
传递时,将使用以下内容进行初始化:
self.name = name
self.time = time
self.something = something
如何做到这一点?
答案 0 :(得分:2)
Python允许使用dict魔术场动态操作类实例。
def __init__(self, list_of_attrs):
for column in list_of_attrs:
self.__dict__[column] = None
此外,您可能希望提供实际值,例如:
def __init__(self, **kwargs):
for name, value in kwargs.items():
self.__dict__[name] = value
Pythonic方式是使用kwargs
,它代表KeyWord ARGumentS。 kwargs
只是一个约定,实际意义由**给出,所以你可以按照自己的意愿命名。
答案 1 :(得分:2)
这是一个想法:使用关键字:
class csv_row:
def __init__(self, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
c = csv_row(id=501, alias="john", shell="bash")
print c.id # 501
print c.alias # john
print c.shell # bash
答案 2 :(得分:2)
已经有几个设施来处理这样的事情。没有必要重新发明轮子:
namedtuple
from collections import namedtuple
headers = ["one", "two", "three"]
CustomRow = namedtuple("CustomRow", headers)
a_row = CustomRow(1, 2, 3)
a_row.one == 1 # True
a_row.two == 2 # True
a_row.three == 3 # True
csv.DictWriter
和csv.DictReader
import csv
with open("my_file.csv", "rb") as f:
reader = csv.DictReader(f, ["one", "two", "three"])
for line in reader:
print line["one"] # prints the 1st column
print line["two"] # etc.
print line["three"] # etc., etc.
答案 3 :(得分:2)
我意识到这并不是你在原评论中所要求的,但是你想过使用csv.DictReader / csv.DictWriter [1] / [2]吗?在创建干净,强大的解决方案时,这与其他答案相结合可能会有所帮助。
答案 4 :(得分:0)
不完全是您所要求的,但万一有人认为这有帮助。
如果您事先知道这些属性,并且只是想避免分配到self
中的重复,您可以像往常一样在__init__
签名中定义一次参数列表,然后迭代超过locals()
并分配给__dict__
:
class csv_row(object):
def __init__(self, name, time, more_stuff):
for k,v in locals().items():
if k != 'self':
self.__dict__[k] = v