-1

压缩代码

# attempt to condense code while preserving the parts
# relevant to the question

from xml.sax import handler, make_parser

class pdosHandler(handler.ContentHandler):
    def __init__(self, data):
        self.data   = data
        self.parts  = { 'energy_values': 0 }
        self.energy_values = []

    def startDocument( self ):
        print "Reading started"

    def startElement(self, name, attrs):
        for key, val in self.parts.iteritems():
            if( name == key ):
                self.parts[key] = 1;

    def characters( self, ch ):
        if self.parts['energy_values'] :
            if ch != '\n':
                self.data.energy_values.append(float(ch.strip()))

def pdosreader(inp, data):
    handler = pdosHandler(data)
    parser = make_parser()
    parser.setContentHandler(handler)
    inFile = open(inp)
    parser.parse(inFile)

    inFile.close()

第 153-155 行:

if( self.parts['energy_values'] ):
    if( ch != '\n' ):
        self.data.energy_values.append( string.atof(normalize_whitespace( ch ) ) )

错误:

Traceback (most recent call last):
  File "siesta_pdos.py", line 286, in <module>
    main()
  File "siesta_pdos.py", line 278, in main
    pdosreader( args[0], data )
  File "siesta_pdos.py", line 262, in pdosreader
    parser.parse( inFile )
  File "/usr/lib/python2.7/xml/sax/expatreader.py", line 107, in parse
    xmlreader.IncrementalParser.parse(self, source)
  File "/usr/lib/python2.7/xml/sax/xmlreader.py", line 123, in parse
    self.feed(buffer)
  File "/usr/lib/python2.7/xml/sax/expatreader.py", line 207, in feed
    self._parser.Parse(data, isFinal)
  File "siesta_pdos.py", line 155, in characters
    self.data.energy_values.append( string.atof(normalize_whitespace( ch ) ) )
  File "/usr/lib/python2.7/string.py", line 388, in atof
    return _float(s)
ValueError: could not convert string to float:

输入文件:

<pdos>
<nspin>2</nspin>
<norbitals>7748</norbitals>
<energy_values>
           -29.99997
           -29.98997
           -29.97996
           ...
           ... (3494 lines skipped)
           ...
             4.97999
             4.98999
             4.99999
</energy_values>
</pdos>

完整输入:http ://dl.dropbox.com/u/10405722/inputfile.dat

完整代码位于:http ://dl.dropbox.com/u/10405722/siesta_pdos.py


代码正确读取前 3116 个值,然后退出并出现错误。请注意,具有较短输入(例如 3000 行)的相同代码可以正常工作。 因此,在我看来,与 atof 无关的缓冲区相关错误。

任何想法?

4

1 回答 1

0

文档说string.atof是

2.0 版后已弃用:使用 float() 内置函数。

您声称这float()不起作用,这可能意味着您的输入无效。print当找出为什么某些东西不能按预期工作时,它非常容易使用

if( ch != '\n' ):
    print repr(ch), repr(ch.strip())
    print repr(normalize_whitespace(ch))
    print repr(float(ch.strip()))
    self.data.energy_values.append(string.atof(normalize_whitespace(ch)))

因为您必须解释 normalize_whitespace,这意味着它是一个不好的同义词;如果您只是将其称为条带,则每个读者都无需查找即可知道它的作用。

万一你不知道repr是为了减少歧义。例如:

>>> x = '1.234'
>>> print x
1.234
>>> print repr(x)
'1.234'
>>> print repr(float(x))
1.234

第一次打印时,不清楚 x 是数字还是字符串。使用 repr,不涉及猜测。

于 2013-08-19T08:43:45.433 回答