Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Python中的文件加载参数_Python_File_Serialization_Input - Fatal编程技术网

从Python中的文件加载参数

从Python中的文件加载参数,python,file,serialization,input,Python,File,Serialization,Input,我正在编写一个Python类来建模一个进程,我想从一个文件初始化参数,比如说'input.dat'。输入文件的格式如下所示 'input.dat'文件: Z0:0 k:0.1 g:1 增量:20 完:300 我写的代码如下。它可以工作,但看起来是多余的和不灵活的。有更好的方法做这项工作吗?例如循环执行readline(),然后匹配关键字 def load(self,filename="input.dat"): FILE = open(filename) s = FILE.rea

我正在编写一个Python类来建模一个进程,我想从一个文件初始化参数,比如说
'input.dat'
。输入文件的格式如下所示

'input.dat'
文件:

Z0:0
k:0.1
g:1
增量:20
完:300
我写的代码如下。它可以工作,但看起来是多余的和不灵活的。有更好的方法做这项工作吗?例如循环执行readline(),然后匹配关键字

def load(self,filename="input.dat"):
    FILE = open(filename)
    s = FILE.readline().split()
    if len(s) is 3:
        self.z0 = [float(s[1]),float(s[2])] # initial state
    s = FILE.readline().split()
    if len(s) is 2:
        self.k = float(s[1])    # kappa
    s = FILE.readline().split()
    if len(s) is 2:
        self.g = float(s[1])
    s = FILE.readline().split()
    if len(s) is 2:
        self.D = float(s[1])    #  Delta
    s = FILE.readline().split()
    if len(s) is 2:
        self.T = float(s[1])    # end time

您可以按如下方式循环文件中的行:

for line in FILE:
    s = line.split
    var = s[0]
    if var == 'z0:':
        self.z0 = [float(s1), float(s2)]
    elif var == 'k:':
         etc. 

等等。

也许这会给你你所需要的:

def load(self,filename='input.dat'):
    with open(filename) as fh:
        for line in fh:
           s = line.split()
           if len(s) == 2:
               setattr(self,s[1],s[2])
           elif len(s) == 3:
               setattr(self,s[1],s[2:])
我也没有包括任何错误检查,但非常方便。

尝试以下方法:

def load(self, filename="input.dat"):
    d = {"Z0": "z0", "k": "k", "g": "g", "Delta": "D", "t_end": "T"}
    FILE = open(filename)
    for line in FILE:
        name, value = line.split(":")
        value = value.strip()
        if " " in value:
            value = map(float, value.split())
        else:
            value = float(value)
        setattr(self, d[name], value)
证明其有效的证据:

>>> class A(object): pass
...
>>> a = A()
>>> load(a)
>>> a.__dict__
{'k': 0.10000000000000001, 'z0': [0.0, 0.0], 'D': 20.0, 'g': 1.0, 'T': 300.0}
大概是这样的:

def load(self,filename="input.dat"):

    # maps names to number of fields they need
    # only necessary for variables with more than 1 field
    argmap = dict(Z0=2)

    # maps config file names to their attribute names on the object
    # if name is the same both places, no need
    namemap = dict(Z0="z0", Delta="D", t_end="T")

    with open(filename) as FILE:
        for line in FILE:
            s = line.split()
            var = s[0].rstrip(":")
            try:
                val = [float(x) for x in s[1:]]
            except ValueError:
                continue
            if len(val) == varmap.get(var, 1):
               if len(val) == 1:
                   val = val[0]
               setattr(self, namemap.get(var, var), val)
  • 如果您可以使用其他类型的文件保存参数,我建议您使用该文件
  • python库是如何轻松地与python一起使用的
  • 要获得更好的介绍,请参阅wiki文章:
  • 这样做的好处是,您可以将参数值读取为列表、映射
  • 你会喜欢的
Python对象有一个内置的
\uuu dict\uu
成员。您可以修改它,然后将属性引用为
obj.key

class Data(object):
  def __init__(self, path='infile.dat'):
    with open(path, 'r') as fo:
      for line in fo.readlines():
        if len(line) < 2: continue

        parts = [s.strip(' :\n') for s in line.split(' ', 1)]
        numbers = [float(s) for s in parts[1].split()]

        # This is optional... do you want single values to be stored in lists?
        if len(numbers) == 1: numbers = numbers[0]
        self.__dict__[parts[0]] = numbers
        # print parts  -- debug

obj = Data('infile.dat')
print obj.g
print obj.Delta
print obj.Z0
为了保持一致性,您可以在我的代码中删除标记为“可选”的行,并将所有对象都放在列表中——不管它们有多少个元素。这将使使用它们变得更加容易,因为您不必担心返回错误。

这里是另一个问题

def splitstrip(s):
    return s.split(':')[1].strip()

with open('input.dat','r') as f:
    a.z0 = [float(x) for x in splitstrip(f.readline()).split(' ')]
    a.k, a.g, a.D, a.T = tuple([float(splitstrip(x)) for x in f.read().rstrip().split('\n')])

)()

假设参数来自安全的地方(由您或用户制作,而不是互联网),只需将参数文件设置为Python文件,
params.py

Z0 = (0, 0)
k = 0.1
g = 1
Delta = 20
t_end = 300
然后在代码中,您只需要:

import params
fancy_calculation(10, k=params.k, delta=params.Delta)
这有两个好处:1)简单,2)可以在参数描述中使用Python的强大功能——在这里特别有用,例如:

k = 0.1
Delta = 20
g = 3 * k + Delta

或者,您可以使用Python的内置或模块。

正如其他人所提到的,在Python中,您可以动态地创建对象属性“”。这意味着您可以执行如下操作,在读入对象时创建
Params
对象。我试图使代码尽可能以数据驱动,因此相对灵活

# maps label to attribute name and types
label_attr_map = {
       "Z0:": ["z0", float, float],
        "k:": [ "k", float],
        "g:": [ "g", float],
    "Delta:": [ "D", float],
    "t_end:": [ "T", float]
}

class Params(object):
    def __init__(self, input_file_name):
        with open(input_file_name, 'r') as input_file:
            for line in input_file:
                row = line.split()
                label = row[0]
                data = row[1:]  # rest of row is data list

                attr = label_attr_map[label][0]
                datatypes = label_attr_map[label][1:]

                values = [(datatypes[i](data[i])) for i in range(len(data))]
                self.__dict__[attr] = values if len(values) > 1 else values[0]


params = Params('input.dat')
print 'params.z0:', params.z0
print 'params.k:', params.k
print 'params.g:', params.g
print 'params.D:', params.D
print 'params.T:', params.T
输出:

params.z0:[0.0,0.0]
参数k:0.1
参数g:1.0
参数D:20.0
参数T:300.0

我发现初始格式比任何一天都好。实际上,我们已经改变了格式,以更好地与python接口。如果您可以更改input.dat,使其看起来更像一本打印精美的python字典,那么您可以插入整个glob并在其上运行eval()。所以在开头和结尾加上括号,在字符串周围加上引号,你会更开心@皮因茨基:是的。不要
eval()
config文件。使用一些安全的工具,如
JSON
ConfigParser
@Tim,基于Python的配置文件在某些情况下非常有用,请参见我的答案,例如:@Tim当然JSON也可以工作。to nos::json格式和python dict格式几乎相同,因此您可以导入json并执行json.loads(file.read())并快速成功地获得所需内容。为什么不导入json或.INI呢?它们都内置在python的stdlib中?或者“导入”(见我的答案)。@benhoyt,我想这更多是为了方便,我相信你的解决方案也能奏效:)
# maps label to attribute name and types
label_attr_map = {
       "Z0:": ["z0", float, float],
        "k:": [ "k", float],
        "g:": [ "g", float],
    "Delta:": [ "D", float],
    "t_end:": [ "T", float]
}

class Params(object):
    def __init__(self, input_file_name):
        with open(input_file_name, 'r') as input_file:
            for line in input_file:
                row = line.split()
                label = row[0]
                data = row[1:]  # rest of row is data list

                attr = label_attr_map[label][0]
                datatypes = label_attr_map[label][1:]

                values = [(datatypes[i](data[i])) for i in range(len(data))]
                self.__dict__[attr] = values if len(values) > 1 else values[0]


params = Params('input.dat')
print 'params.z0:', params.z0
print 'params.k:', params.k
print 'params.g:', params.g
print 'params.D:', params.D
print 'params.T:', params.T