创建类之后,如何在不使用模块的情况下将信息从csv添加到python对象

e3bfsja2  于 2022-12-06  发布在  Python
关注(0)|答案(3)|浏览(126)

我正在努力理解类/对象,并对它们使用csv。
我有一个26行的CSV,1行是标题,另一行包含信息行。

id,food,food_print,cal1,cal2,expi1999,expi2000,expi2001
1,bun,bun_bun,45.3434,199.32323,23.3333,45.4444,33.33333
2,burger,burger_bun,45.342343,200.34243,34.3333,0,9
3,pickle,pickle_seed,67.345454,34.3434,34,56,33
4,chicken,chicken_egg,44.34343,43.343343,43,434,34343

我有我的类如下:

class City(object):
    def __init__(self, food = 'n/a', foodprint = 'n/a', cal1 = -999, cal2 = -999, 
    expi1999 = -999, expi2000 = -999, expi2001 = -999) 
        self.food = food
        self.foodprint = foodprint
        self.cal1 = cal1
        self.cal2 = cal2
        self.expi1999 = expi1999
        self.expi2000 = expi2000
        self.expi2001 = expi2001

meals = []

foodfile = open('Food.csv', 'rt')
headers = foodfile.readline().strip().split(',')
headers = headers.split(',')

for line in foodfile:
    foodfields = foodfile.readline().strip().split(',')

如何将food csv中的行写入类中要引用的对象?

flvlnr44

flvlnr441#

假设每行中的所有列都已填充:尝试:

for line in foodfile:
    foodfields = foodfile.readline().strip().split(',')
    meals.append(City(foodfields[1],foodfields[2],foodfields[3],foodfields[4],foodfields[5],foodfields[6],foodfields[7]))
6pp0gazn

6pp0gazn2#

false音调以避免动态类。
因为您的代码在将来的更改中变得不可预测。请改用数据类。
此外,此行为还允许您在与任何可调用对象进行数据交换期间将此“数据模型”作为注解引用。

from dataclasses import dataclass
@dataclass
class City:
    food: str = 'n/a'
    foodprint: str = 'n/a'
    cal1: int = -999
    cal2: int = -999
    expi1999: int = -999 
    expi2000: int = -999
    expi2001: int = -999

但如果要现在怎么做-setattr函数存在于全局命名空间中。

class DynamicContainer:
    @classmethod
    def create(cls, headers: list[str], data: list[str]):
        obj = cls()
        for header, value in zip(headers, data):
            setattr(obj, header, value)
        return obj
        
headers = 'id,food,food_print,cal1,cal2,expi1999,expi2000,expi2001'.split(',')
data = '1,bun,bun_bun,45.3434,199.32323,23.3333,45.4444,33.33333'.split(',')
cont = DynamicContainer.create(headers, data)

print(cont.id, cont.cal1, cont.expi2000)
m4pnthwp

m4pnthwp3#

我会这样做:

import csv

class City(object):
    def __init__(self, food=None, foodprint=None, cal1=None, cal2=None,  expi1999=None, expi2000=None, expi2001=None):
        self.food = food
        self.foodprint = foodprint
        self.cal1 = float(cal1)
        self.cal2 = float(cal2)
        self.expi1999 = float(expi1999)
        self.expi2000 = float(expi2000)
        self.expi2001 = float(expi2001)
        
    def __repr__(self):
        return (
            f"{self.__class__.__name__}("
            f"food={self.food!r}"
            f", "
            f"food_print={self.foodprint!r}"
            f", "
            f"cal1={self.cal1!r}"
            f", "
            f"cal2={self.cal2!r}"
            f", "
            f"expi1999={self.expi1999!r}"
            f", "
            f"expi2000={self.expi2000!r}"
            f", "
            f"expi2001={self.expi2001!r}"
            f")"
        )

with open("Food.csv") as stream:
    next(stream)  # Skip the header row
    reader = csv.reader(stream)
    meals = [City(*row[1:]) for row in reader]

rows的外观如下所示:

[City(food='bun', food_print='bun_bun', cal1=45.3434, cal2=199.32323, expi1999=23.3333, expi2000=45.4444, expi2001=33.33333),
 City(food='burger', food_print='burger_bun', cal1=45.342343, cal2=200.34243, expi1999=34.3333, expi2000=0.0, expi2001=9.0),
 City(food='pickle', food_print='pickle_seed', cal1=67.345454, cal2=34.3434, expi1999=34.0, expi2000=56.0, expi2001=33.0),
 City(food='chicken', food_print='chicken_egg', cal1=44.34343, cal2=43.343343, expi1999=43.0, expi2000=434.0, expi2001=34343.0)]

备注

  • repr函数是显示类对象的内容,可以忽略它
  • 我使用csv模块来简化CSV数据的解析
  • 我还将值转换为浮点数。

相关问题