创建一个使用文本文件继承自dict的类 - python

时间:2014-09-26 08:15:55

标签: python class object dictionary

我有一个文件:

1 23
2 21
5 23
561 2
73 19781

使用此功能:

def readx(x):
    return {int(line.split()[0]):int(line.split()[1]) for line in x.split('\n')}

我可以得到这个:

{1: 23, 2: 21, 5: 23, 73: 19781, 561: 2}

但是我需要把它放到某种类对象中,所以我尝试了这个:

z = """1 23
2 21
5 23
561 2
73 19781"""

def readx(x):
    return {int(line.split()[0]):int(line.split()[1]) for line in x.split('\n')}


class Foo(dict):
    def __init__(self, x):
        self = readx(x)

f = Foo(z)
print f

但它返回None而不是字典。

  1. 有更多的pythonic方式readx()吗?它现在有点难看。
  2. 如何让类对象工作并使用键和值制作foo dict?

3 个答案:

答案 0 :(得分:3)

使用super

class Foo(dict):
    def __init__(self, x):
        super(Foo, self).__init__(readx(x))

这将调用数据上的dict构造函数,将其复制到对象中。

请注意,这也适用于Python 3。

答案 1 :(得分:2)

没有super的替代方案是:

class Foo(dict):
    def __init__(self, x):
        for k, v in readx(x).items():
            self[k] = v

答案 2 :(得分:2)

对于第一个问题,是的,这种理解有点难以理解,一个简单的循环可能会更好:

def read_dict(fp):
   d = {}
   for line in fp:
        k, v = line.strip().split();
        d[int(k)] = int(v)
   return d

其中fp是任何可迭代的,例如文件对象。

对于第二个问题,如果你的__init__没有做任何有用的工作,只需去除它,并将read的结果作为参数传递给构造函数,然后透明地调用父dict.__init__

class Foo(dict):
    # stuff

with open(path) as fp:
   foo = Foo(read_dict(fp))

或者,在read中实例化Foo并返回它:

 def read_foo(fp):
   d = Foo()
   for line in fp:
       # etc, just as above

然后简单地

with open(path) as fp:
   foo = read_foo(fp)

您还可以在Foo中使read类方法更好地构建代码:

class Foo(dict):

   @classmethod
   def read(cls, fp):
       d = cls()
       for line in fp:
          #etc

然后:

with open(path) as fp:
   foo = Foo.read(fp)

最后,如果您想直接从fp对象初始化Foo,则需要__init__

class Foo(dict):
    def __init__(self, fp):
        for line in fp:
            k, v = line.strip().split()
            self[int(k)] = int(v)

然后

x = Foo(fp)

但是,应谨慎使用此代码,因为它违反了Liskov substitution principle,这通常不是一件好事。