Перенаправить вывод из флагов python в html [duplicate]

Использование интерфейсов является ключевым фактором, позволяющим легко проверить ваш код в дополнение к удалению ненужных связей между вашими классами. Создавая интерфейс, который определяет операции над вашим классом, вы разрешаете классам, которые хотят использовать эту функциональность, возможность использовать его, не зависимо от вашего класса реализации напрямую. Если позже вы решите изменить и использовать другую реализацию, вам нужно изменить только часть кода, в котором реализована реализация. Остальная часть кода не должна меняться, потому что это зависит от интерфейса, а не от класса реализации.

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

EDIT: Ниже приведена ссылка на статью, где Эрих Гамма обсуждает свою цитату «Программа для интерфейса, а не реализация».

http://www.artima.com/lejava/articles/designprinciples.html

10
задан davidism 11 August 2015 в 20:18
поделиться

1 ответ

Вы можете передавать данные в ответ, но вы не можете динамически обновлять шаблон так, как вы описываете. Шаблон создается один раз на стороне сервера, а затем отправляется клиенту. Вам нужно будет использовать JavaScript для чтения потокового ответа и вывода данных на стороне клиента.

Используйте XMLHttpRequest, чтобы сделать запрос к конечной точке, которая будет передавать данные. Затем периодически читайте поток, пока он не будет выполнен.

В этом примере используется очень простой формат сообщения: одна строка данных, за которой следует новая строка. Конечно, вы можете так же усложниться в разборе, сколько хотите, пока есть способ идентифицировать каждое сообщение. Например, вы можете вернуть объект JSON и декодировать его на клиенте.

from time import sleep
from flask import Flask, render_template
from math import sqrt

app = Flask(__name__)

@app.route('/')
def index():
    # render the template (below) that will use JavaScript to read the stream
    return render_template('index.html')

@app.route('/stream_sqrt')
def stream():
    def generate():
        for i in range(500):
            yield '{}\n'.format(sqrt(i))
            sleep(1)

    return app.response_class(generate(), mimetype='text/plain')

app.run()
<p>This is the latest output: <span id="latest"></span></p>
<p>This is all the output:</p>
<ul id="output"></ul>
<script>
    var latest = document.getElementById('latest');
    var output = document.getElementById('output');

    var xhr = new XMLHttpRequest();
    xhr.open('GET', '{{ url_for('stream') }}');
    xhr.send();
    var position = 0;

    function handleNewData() {
        // the response text include the entire response so far
        // split the messages, then take the messages that haven't been handled yet
        // position tracks how many messages have been handled
        // messages end with a newline, so split will always show one extra empty message at the end
        var messages = xhr.responseText.split('\n');
        messages.slice(position, -1).forEach(function(value) {
            latest.textContent = value;  // update the latest value in place
            // build and append a new item to a list to log all output
            var item = document.createElement('li');
            item.textContent = value;
            output.appendChild(item);
        });
        position = messages.length - 1;
    }

    var timer;
    timer = setInterval(function() {
        // check the response for new data
        handleNewData();
        // stop checking once the response has ended
        if (xhr.readyState == XMLHttpRequest.DONE) {
            clearInterval(timer);
            latest.textContent = 'Done';
        }
    }, 1000);
</script>
11
ответ дан davidism 22 August 2018 в 17:31
поделиться
  • 1
    Несколько вопросов: 1. В команде xhr.open(), «поток», это имя функции Python, которую она слушает? 2. Есть ли способ не получать все предыдущее сообщение каждый раз (и удалить необходимость в slice(), переменной position и т. Д.? – JeffThompson 11 August 2015 в 22:57
  • 2
    {{ url_for('stream') }} генерирует URL-адрес конечной точке stream при рендеринге шаблона. Невозможно получить только новые данные, вам нужно отслеживать, что было прочитано до сих пор. – davidism 11 August 2015 в 23:00
Другие вопросы по тегам:

Похожие вопросы: