从列表中创建一个__init__类

时间:2014-04-24 17:17:18

标签: python python-2.7

我有类似的东西,硬编码:

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

如何做到这一点?

5 个答案:

答案 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.DictWritercsv.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]吗?在创建干净,强大的解决方案时,这与其他答案相结合可能会有所帮助。

  1. https://docs.python.org/2/library/csv.html
  2. https://docs.python.org/3/library/csv.html

答案 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