Python 2.6 linecache.getline () и стандартный ввод.Как это работает? - PullRequest
0 голосов
/ 23 ноября 2018

У меня есть скрипт, который проходит по строкам ввода, чтобы найти вхождение строки идентификатора, отслеживая количество белья.Затем выполняется обратный ход ввода для отслеживания отношений parentID / childID.Скрипт принимает либо файл журнала, используя флаг '-f' в качестве аргумента, либо содержимое stdin из канала.Лог-файл в качестве входной части работает просто отлично, но чтение из stdin, похоже, не работает.

Ради разумной ясности я включил ту часть сценария, которая касается этого, но не ожидаю, что она будетв состоянии запустить это.Это просто, чтобы показать вам, что происходит (любой, кто работает в финансовых службах по протоколу FIX, узнает несколько вещей):

import os
import sys
import linecache

from types import *
from ____ import FixMessage   # custom message class that is used throughout

# Feel free to ignore all the getArgs and validation crap
def getArgs():
    import argparse
    parser = argparse.ArgumentParser(
               description='Get amendment history.')
    parser.add_argument('-f', '--file',
               help="input logfile.'")
    args = parser.parse_args()

    return validateArgs(args)


def validateArgs(args):
    try:
        if sys.stdin.isatty():
            if args.file:
                assert os.path.isfile(args.file.strip('\n')), \
                    'File "{0}" does not exist'.format(args.file)
                args.file = open(args.file, 'r')
        else:
            args.file = sys.stdin
        assert args.file, \
            "Please either include a file with '-f' or pipe some text in"
    except AssertionError as err:
        print err
        exit(1)

    return args    


defGetMessageTrail(logfile, orderId):
    # some input validation
    if isinstance(logfile, StringType):
        try: logfile = open(logfile, 'r')
        except IOError as err: exit(1)
    elif not isinstance(logfile, FileType):
        raise TypeError(
              'Expected FileType and got {0}'.format(type(logfile)))

    linenum  = 0

    # This retrieves the message containing the orderID as well as the linenum
    for line in logfile:
        linenum += 1
        if orderId in line:
            # FixMessage is a custom class that is treated here like
            # a dictionary with some metadata
            # Missing dict keys return 'None'
            # .isvalid is bool results of some text validation
            # .direction is either incoming or outgoing
            # thats all you really need to know
            msg = FixMessage(line)
            if msg.isvalid and msg.direction == 'Incoming':
                yield msg
                break

    # If there is a message parentID, it would be in msg['41']
    if msg['41']:
        messages = findParentMessages(logfile, startline=linenum, msg['41'])
        for msg in messages: yield msg



def findParentMessages(logfile, startline, targetId):
    # Some more input validation
    assert isinstance(logfile, FileType)
    assert isinstance(startline, IntType)
    assert isinstance(targetId, StringType)

    # should just make a integer decrementing generator,
    # but this is fine for the example
    for linenum in range(startline)[::-1]:
        # *** This is where the question lies... ***
        # print(logfile.name) # returns "<stdin>"
        line = linecache.getline(logfile.name, linenum)
        if 'Incoming' in line and '11=' + targetId in line:
            msg = FixMessage(line)
            yield msg
            if msg['41']: findParentMessages(logfile, linenum, msg['41'])
            else: break


def main():
    log = getArgs().file
    trail = getMessageTrail(log, 'ORDER123')


if __name__ == '__main__': main()

Вопрос в том, как работает linecache.getline, когда дело доходит до чтениястандартный как файл?отличается ли он от того, как он будет работать, если ему дать обычное имя файла?

1 Ответ

0 голосов
/ 23 ноября 2018

linecache.getline () принимает имя файла, а не объект файла.Он не предназначен для такой работы, поскольку имя файла передается вызовам, таким как open () и os.stat ().

Для справки: https://github.com/python/cpython/blob/2.6/Lib/linecache.py

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...