首页 > 解决方案 > 将值从 csv 文件传递​​到 python 类

问题描述

class Devices:

    def __init__(self, fqdn):
        self.fqdn = fqdn

    def domain(self, fqdn):
        self.fqdn = fqdn.split(".")
        if fqdn.split(".")[1] == 'sa':
            return 'South America'
        elif fqdn.split(".")[1] == 'na':
            return 'North America'
        elif fqdn.split(".")[1] == 'ap':
            return 'Asia Pacific'
        elif fqdn.split(".")[1] == 'ea':
            return "Europe"


device_1 = Devices('retuyr.sa.abc.com')
device_2 = Devices('agtrah.na.abc.com')
domain1 = Devices('retuyr.sa.abc.com')
domain2 = Devices('agtrah.na.abc.com')

print('FQDN: %s' % device_1.fqdn)
print('Region is: %s' % domain1.domain(fqdn='retuyr.sa.abc.com'))
print('FQDN: %s' % device_2.fqdn)
print('Region is: %s' % domain2.domain(fqdn='agtrah.na.abc.com'))

我知道可能有其他方法可以在这里找到该区域,并且没有必要进行“拆分”。但是,我还有一些其他功能要在子类中运行,所以需要保持这种方式。

这里的输出是:

FQDN: retuyr.sa.abc.com
Region is: South America
FQDN: agtrah.na.abc.com
Region is: North America

现在,我能够做到这一点。但是,我想要的是从 csv 文件中读取一个特定的列,该列具有 FQDN 名称并遍历该文件中的所有名称。csv 文件中有很多列,而且它是一个非常大的文件。我应该如何解析这个类中的那些值。请帮忙!

编辑:

我的 CSV 看起来像这样:

Server, FQDN, IP_Address, Name, primary1, Address
abc1, retuyr.sa.abc.com, 10.10.10.1, someinfo, someaddress
abc1, agtrah.na.abc.com, 10.10.10.2, someinfo, someaddress
xyz2, somemorefqdns, 10.10.10.3, someinfo, someaddress
...
...

这是一个非常大的 csv 文件。但我在这里关心的是,根据我的 FOR 循环条件,仅获取 FQDN 并获取所需的区域。我想要的输出将保持不变。唯一的区别是,我不想手动输入所有这些 FQDN 名称。只是希望他们从 csv 文件中读取它。

标签: pythonpython-3.xcsvclass

解决方案


按照 MooingRawr引用的帖子中的建议使用pandas是一种解决方案,另一种是仅使用内置的csv.DictReader

此外,用一个属性值初始化一个类实例似乎非常适得其反,只是用你真正想要的值立即覆盖它。我也不认为彻底改变该属性的类型是一种好习惯。如果初始属性值无关紧要,那么您可以将方法保留为类方法。

此外,我发现查找字典比长 if 语句更简洁且更易于维护。

import csv

DOMAINLOOKUP = {
    'sa': 'South America',
    'na': 'North America',
    'ap': 'Asia Pacific',
    'ea': "Europe",
}

class Devices():
    def __init__(self,fqdn):
        self.fqdn = fqdn

    @property
    def fqdnparts(self):
        """ Returns the fqdn split into its individual components (dot delineated) """
        ## In your original code, calling domain replaced the self.fqdn
        ## string with a list, thus making it impossible to predict the type
        ## of fqdn on any given object, so I created a new attribute to
        ## interface with the split value
        return self.fqdn.split(".")

    @property
    def domain(self):
        code = self.fqdnparts[1]
        return DOMAINLOOKUP[code]

def initializefile(file):
    with open(file) as f:
        return convertrows(csv.DictReader(f))

def convertrows(rows):
    return [Devices(row['FQDN']) for row in rows]

file = r"My\file.csv"
devices = initializefile(file)

for device in devices:
    print(f"FDQN: {device.fqdn}, Region: {device.domain}")
## Prints
## > "FDQN: retuyr.sa.abc.com, Region: South America"
## > "FDQN: agtrah.na.abc.com, Region: North America"

推荐阅读