我有一个文件:
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而不是字典。
readx()
吗?它现在有点难看。foo
dict? 答案 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,这通常不是一件好事。