2017-08-08 68 views
6

TL; DR:Czy użycie funkcji print() zbytnio powoduje błąd?

print() wynik nie jest aktualizowana w konsoli Windows. Wykonuje się dobrze w IDLE. Program jest uruchamiany, mimo że Windows Console nie aktualizuje się.

Tło

Mam plik, który zawiera test.py:

Edit: wliczony warunki, które kiedyś sprawdzić, czy konsola została aktualizacją. Ostatecznie seria wartości X nigdy nie drukuje ponownie w konsoli, a konsola nigdy nie przewija kopii zapasowej (tak jak zwykle, gdy dane wyjściowe są generowane na dole).

count = 0 
while True: 
    print ("True") 
    count += 1 
    if count == 10: 
      print ("XXXXXXXXX") 
      count = 0 

Gdy uruchomię to w cmd.exe to oczywiście drukuje bardzo dużą liczbę True.

Jednak po około 25 sekundach działania przestaje drukować, chociaż program nadal działa i można go zobaczyć w Menedżerze zadań.

Mam program z pewnymi wskaźnikami postępu, które kończą na pozostaniu na poziomie 50%, mimo że przenoszą się one znacznie poza 50%, ponieważ po prostu print() nie wyświetla się na wyjściu konsoli.

Edytuj: Prawdziwy problem z przypadkiem użycia.

Powyższy kod był tylko plikiem testowym, aby sprawdzić, czy drukowanie w konsoli zostało zatrzymane we wszystkich programach, a nie w tym, który był uruchomiony. W praktyce, moje odciski program do konsoli i wygląda następująco:

line [10] >> Progress 05% 

Gdzie line [10] nie jest prawdziwy ale ja po prostu wpisane tutaj, aby pokazać, że print() wysyła do tej linii w oknie konsoli. Ponieważ mój program kontynuuje przyrosty:

line [10] >> Progress 06% 
line [10] >> Progress 11% 
. 
. 
. 
line [10] >> Progress 50% 

Za każdym razem line [10] jest nadpisywany. I używać znaków ewakuacyjnych ANSI i colorama aby przesunąć kursor Console odpowiednio:

print('\x1b[1000D\x1b[1A')

ten przesuwa kursor w lewo i 1000 kolumn 1 wiersz w górę (tak na początku poprzedniej linii).

Coś się dzieje, gdzie print("Progress " + prog + "%") nie pokazuje się już w konsoli bo w końcu następny bit Pythona zostanie wykonany:

line [11] >> Program Complete...

I zweryfikowała wypadkowe, które się umieścić w folderze. Program nadal działał, a konsola nie aktualizowała się.

Edytuj: Oto skrypt uruchamiający aktualizacje do stdout.

def check_queue(q, dates, dct): 
    out = 0 
    height = 0 

    # print the initial columns and rows of output 
    # each cell has a unique id 
    # so they are stored in a dictionary 
    # then I convert to list to print by subscripting 
    for x in range(0, len(list(dct.values())), 3): 
     print("\t\t".join(list(dct.values())[x:x+3])) 
     height +=1 # to determine where the top is for cursor 

    while True: 
     if out != (len(dates) * 2): 
      try: 
       status = q.get_nowait() 
       dct[status[1]] = status[2] 
       print('\x1b[1000D\x1b[' + str(height + 1) + 'A') 

       # since there was a message that means a value was updated 
       for x in range(0, len(list(dct.values())), 3): 
        print("\t\t".join(list(dct.values())[x:x+3])) 

       if status[0] == 'S' or 'C' or 'F': 
        out += 1 
      except queue.Empty: 
       pass 
    else: 
     break 

Krótko mówiąc, przekazuję wiadomość do kolejki z wątku. Następnie aktualizuję słownik zawierający unikalne identyfikatory komórek. Aktualizuję wartość, przesuwaję kursor w konsoli na lewą górną pozycję drukowanej listy i drukuję nad nią.

Pytanie:

Przy użyciu stdout, istnieje limit, ile razy można na niej drukować w czasie?

+4

Co sprawia, że ​​przestajesz drukować? – user2357112

+3

Python z pewnością nie ma ograniczeń co do ilości danych wyjściowych, które proces może wygenerować. –

+0

@ user2357112 Zobacz teraz blok kodu. Zaktualizowałem go, testowałem, aby się tego upewnić. Co się dzieje, ostatecznie seria "X" nigdy się nie pojawia i konsola nigdy nie przewija poprzedniej wersji. To prowadzi mnie do przekonania, że ​​nie jest to już druk. – datta

Odpowiedz

4

Może to być złudzenie (może dlatego, że w konsoli jest maksymalna granica linii, a nowe zastępują pierwsze).

Nie ma zdecydowanie limitu, ile możesz print. Można to sprawdzić w czymś, co zmienia każdej iteracji, na przykład pętlę, który zlicza liczbę powtórzeń:

import itertools 
for i in itertools.count(): 
    print(i, "True") 
+0

Zaczynam myśleć, że może to być przypadek osiągnięcia liczby linii. Jednak nadpisuję linie w tym samym miejscu. Czy to podwójne liczenie? – datta

+0

Nie rozumiem, co masz na myśli. Niektóre konsole działają jak kolejki FIFO. Po osiągnięciu określonego limitu odrzucają najstarszą linię, aby wydrukować najnowszą. Tak jak wspomniałem w odpowiedzi. Ale w każdym przypadku możesz zaktualizować swoje pytanie, jeśli to nie rozwiąże twojego pytania i wyjaśnić ** dlaczego ** to nie rozwiązuje twojego problemu? – MSeifert

+0

Proszę zobaczyć mój post edycji dla mojego przypadku użycia – datta

1

brzmi jak to może być ograniczenie systemu, a nie kwestia proces Python? Nigdy nie natknąć a „hang” związane wydrukować oświadczenia (lub dowolną wbudowaną funkcję), ale może warto spojrzeć na wykonanie map i pamięci:

High Memory Usage Using Python Multiprocessing

Jeśli chodzi o ile Czasy, które można wydrukować w określonym czasie, to prawie wyłącznie szybkość, z jaką system wykonuje kod. Można przeprowadzić testy porównawcze (czas wykonania/liczbę wykonań) na kilku platformach, aby przetestować wydajność za pomocą określonych specyfikacji systemu, ale powiedziałbym, że prawdopodobną przyczyną problemu jest związany system/środowisko.

2

Nie mogę odtworzyć problemu w systemie Windows 10 przy użyciu 64-bitowego Pythona 3.6.2 i colorama 0.3.9. Oto prosty przykład, który przetestowałem:

import colorama 
colorama.init() 

def test(M=10, N=1000): 
    for x in range(M): 
     print('spam') 
    for n in range(N): 
     print('\x1b[1000D\x1b[' + str(M + 1) + 'A') 
     for m in range(M): 
      print('spam', m, n) 

Każde przejście pomyślnie zastępuje poprzednie linie. Oto ostateczne wyjście z pętli n (1000) razy:

>>> test() 
spam 0 999 
spam 1 999 
spam 2 999 
spam 3 999 
spam 4 999 
spam 5 999 
spam 6 999 
spam 7 999 
spam 8 999 
spam 9 999 

Jeśli ten przykład nie dla was, proszę zaktualizować pytanie i obejmują wersje systemu Windows, Python i COLORAMA które testujemy.

+0

Używam Windows 7, Python 3.6.0 i najnowszą wersję colorama. Co ciekawe, nawet bez użycia funkcji coloroma, stdout przestaje być aktualizowany w konsoli (na przykład moja pętla 'while' w pytaniu). – datta

+0

Co z przykładem w tej odpowiedzi? – eryksun