Writing/parsing a fixed width file using Python

前端 未结 8 1714
清歌不尽
清歌不尽 2020-12-14 11:01

I\'m a newbie to Python and I\'m looking at using it to write some hairy EDI stuff that our supplier requires.

Basically they need an 80-character fixed width text f

相关标签:
8条回答
  • 2020-12-14 11:50

    You can convert the string to a list and do the slice manipulation.

    >>> text = list("some text")
    >>> text[0:4] = list("fine")
    >>> text
    ['f', 'i', 'n', 'e', ' ', 't', 'e', 'x', 't']
    >>> text[0:4] = list("all")
    >>> text
    ['a', 'l', 'l', ' ', 't', 'e', 'x', 't']
    >>> import string
    >>> string.join(text, "")
    'all text'
    
    0 讨论(0)
  • 2020-12-14 11:53

    Hopefully I understand what you're looking for: some way to conveniently identify each part of the line by a simple variable, but output it padded to the correct width?

    The snippet below may give you what you want

    class FixWidthFieldLine(object):
    
        fields = (('foo', 10),
                  ('bar', 30),
                  ('ooga', 30),
                  ('booga', 10))
    
        def __init__(self):
            self.foo = ''
            self.bar = ''
            self.ooga = ''
            self.booga = ''
    
        def __str__(self):
            return ''.join([getattr(self, field_name).ljust(width) 
                            for field_name, width in self.fields])
    
    f = FixWidthFieldLine()
    f.foo = 'hi'
    f.bar = 'joe'
    f.ooga = 'howya'
    f.booga = 'doin?'
    
    print f
    

    This yields:

    hi        joe                           howya                         doing     
    

    It works by storing a class-level variable, fields which records the order in which each field should appear in the output, together with the number of columns that field should have. There are correspondingly-named instance variables in the __init__ that are set to an empty string initially.

    The __str__ method outputs these values as a string. It uses a list comprehension over the class-level fields attribute, looking up the instance value for each field by name, and then left-justifying it's output according to the columns. The resulting list of fields is then joined together by an empty string.

    Note this doesn't parse input, though you could easily override the constructor to take a string and parse the columns according to the field and field widths in fields. It also doesn't check for instance values that are longer than their allotted width.

    0 讨论(0)
提交回复
热议问题