web-dev-qa-db-fra.com

Effacer le terminal en Python

Existe-t-il une méthode standard "livré avec piles" pour effacer l'écran du terminal d'un script Python, ou dois-je utiliser des sorts (les bibliothèques, pas les mots)?

164
Stefano Borini

Qu'en est-il des séquences d'échappement?

print(chr(27) + "[2J")
93
Joril

Une solution simple et multiplate-forme consisterait à utiliser la commande cls sous Windows ou clear sur les systèmes Unix. Utilisé avec os.system , cela fait un one-liner Nice:

import os
os.system('cls' if os.name == 'nt' else 'clear')
253
poke

Pourquoi personne n'a parlé de faire simplement Ctrl+L sous Windows ou Cmd+L sous Mac. Sûrement le moyen le plus simple de nettoyer l'écran.

68
sarath joseph

Si vous utilisez un système Linux/UNIX, le travail consiste à imprimer la séquence d'échappement ANSI pour effacer l'écran. Vous voudrez également déplacer le curseur en haut de l'écran. Cela fonctionnera sur n'importe quel terminal prenant en charge ANSI.

import sys
sys.stderr.write("\x1b[2J\x1b[H")

Cela ne fonctionnera sous Windows que si la prise en charge ANSI a été activée. Il peut y avoir une séquence de contrôle équivalente pour Windows, mais je ne le sais pas.

35
Dave Kirby

Pour Windows, Mac et Linux, vous pouvez utiliser le code suivant:

import subprocess, platform

if platform.system()=="Windows":
    subprocess.Popen("cls", Shell=True).communicate() #I like to use this instead of subprocess.call since for multi-Word commands you can just type it out, granted this is just cls and subprocess.call should work fine 
else: #Linux and Mac
    print("\033c", end="")

jamesnotjim a testé print("\033c", end="") pour Mac, et je l'ai testé sous Linux et Windows (cela ne fonctionne pas pour Windows, d'où le code qui appelle cls). Je ne me souviens plus de qui j’avais vu pour la première fois utiliser print ("\ 033c") et/ou la version printf: subprocess.Popen("printf '\033c'", Shell=True).communicate().

rolika a fait remarquer que end="" l'empêcherait d'imprimer une nouvelle ligne par la suite.

27
Shule

Quant à moi, la variante la plus élégante:

import os
os.system('cls||clear')
22
Vasiliy Rusin

Vous pouvez essayer de vous appuyer sur clear, mais il se peut qu’il ne soit pas disponible sur toutes les distributions Linux. Sur Windows, utilisez les clés comme vous l'avez mentionné.

import subprocess
import platform

def clear():
    subprocess.Popen( "cls" if platform.system() == "Windows" else "clear", Shell=True)

clear()

Remarque: prendre le contrôle de l'écran du terminal peut être considéré comme une mauvaise forme. Envisagez-vous d'utiliser une option? Il serait probablement préférable de laisser l’utilisateur décider s’il souhaite effacer l’écran.

8
Rod

Une solution Pure Python.
Ne repose ni sur ANSI, ni sur des commandes externes.
.__ Seul votre terminal doit pouvoir vous dire combien de lignes sont en vue.

from shutil import get_terminal_size
print("\n" * get_terminal_size().lines, end='')

Version Python> = 3.3.0

7
mid_kid

Je suis tombé sur ça il y a quelque temps

def clearscreen(numlines=100):
  """Clear the console.
numlines is an optional argument used only as a fall-back.
"""
# Thanks to Steven D'Aprano, http://www.velocityreviews.com/forums

  if os.name == "posix":
    # Unix/Linux/MacOS/BSD/etc
    os.system('clear')
  Elif os.name in ("nt", "dos", "ce"):
    # DOS/Windows
    os.system('CLS')
  else:
    # Fallback for other operating systems.
    print('\n' * numlines)

Ensuite, utilisez clearscreen ()

5
Short

Alors je pensais que jetterais mes deux sous ici ...

Personne n’a fourni une vraie réponse à la question OP, semble-t-il, tout le monde répond par «NO DONT USE os.system () c’est un mal !!!» sans explication ou fournit une solution qui repose sur l’impression de nouvelles lignes.

Pour ceux qui ont besoin d'effacer l'écran du terminal et de revenir en arrière, pour une raison quelconque, vous pouvez utiliser le code suivant:

import os

def clear():
    '''
    Clears the terminal screen and scroll back to present
    the user with a Nice clean, new screen. Useful for managing
    menu screens in terminal applications.
    '''
    os.system('cls' if os.name == 'nt' else 'echo -e \\\\033c')

print('A bunch of garbage so we can garble up the screen...')
clear()

# Same effect, less characters...

def clear():
    '''
    Clears the terminal screen and scroll back to present
    the user with a Nice clean, new screen. Useful for managing
    menu screens in terminal applications.
    '''
    os.system('cls||echo -e \\\\033c')

Cela a l'effet désiré du PO. Il utilise effectivement la commande os.system (), donc si c'est mal et que quelqu'un connaît un moyen de l'implémenter en utilisant subprocess.call (), veuillez commenter, car je préférerais également utiliser un sous-processus mais je ne le connais pas du tout.

4
StarKiller4011

Si vous souhaitez effacer votre terminal lorsque vous utilisez un shell Python. Ensuite, vous pouvez faire ce qui suit pour effacer l’écran

import os
os.system('clear')
3
Aditya Mishra

Cela fonctionnera dans les deux versions Python2 OR Python3

print (u"{}[2J{}[;H".format(chr(27), chr(27)))
3
Nanhe Kumar

Vous pouvez utiliser la fonction call() pour exécuter les commandes du terminal:

from subprocess import call
call("clear")
2
Arash Hatami

Cette fonction fonctionne dans gnome-terminal car, par défaut, elle reconnaît les séquences d'échappement ANSI. Il vous donne une distance CLEAN Prompt rows_max à partir du bas du terminal, mais aussi précisément de l'endroit où il a été appelé. Vous donne le contrôle complet sur combien d'effacer.

def clear(rows=-1, rows_max=None, *, calling_line=True, absolute=None,
          store_max=[]):
    """clear(rows=-1, rows_max=None)
clear(0, -1) # Restore auto-determining rows_max
clear(calling_line=False) # Don't clear calling line
clear(absolute=5) # Absolutely clear out to 5 rows up"""
    from os import linesep
    if rows_max and rows_max != -1:
        store_max[:] = [rows_max, False]
    Elif not store_max or store_max[1] or rows_max == -1 or absolute:
        try:
            from shutil import get_terminal_size
            columns_max, rows_max = get_terminal_size()
        except ImportError:
            columns_max, rows_max = 80, 24
        if absolute is None:
            store_max[:] = [rows_max, True]
    if store_max:
        if rows == -1:
            rows = store_max[0]
        Elif isinstance(rows, float):
            rows = round(store_max[0] * rows)
        if rows > store_max[0] - 2:
            rows = store_max[0] - 2
    if absolute is None:
        s = ('\033[1A' + ' ' * 30 if calling_line else '') + linesep * rows
    else:
        s = '\033[{}A'.format(absolute + 2) + linesep
        if absolute > rows_max - 2:
            absolute = rows_max - 2
        s += (' ' * columns_max + linesep) * absolute + ' ' * columns_max
        rows = absolute
    print(s + '\033[{}A'.format(rows + 1))

La mise en oeuvre:

clear() # Clear all, TRIES to automatically get terminal height
clear(800, 24) # Clear all, set 24 as terminal (max) height
clear(12) # Clear half of terminal below if 24 is its height
clear(1000) # Clear to terminal height - 2 (24 - 2)
clear(0.5) # float factor 0.0 - 1.0 of terminal height (0.5 * 24 = 12)
clear() # Clear to rows_max - 2 of user given rows_max (24 - 2)
clear(0, 14) # Clear line, reset rows_max to half of 24 (14-2)
clear(0) # Just clear the line
clear(0, -1) # Clear line, restore auto-determining rows_max
clear(calling_line=False) # Clear all, don't clear calling line
clear(absolute=5) # Absolutely clear out to 5 rows up

Paramètres: rows est le nombre de lignes de texte en clair à ajouter entre le message Invite et le bas du terminal. rows_max est la hauteur du terminal (ou la hauteur maximale d'effacement) dans les lignes de texte; il ne doit être défini qu'une seule fois, mais peut être réinitialisé à tout moment. *, dans le troisième paramètre position signifie que tous les paramètres suivants sont uniquement des mots clés (par exemple, clear (absolute = 5)). calling_line=True (par défaut) fonctionne mieux en mode interactif. calling_line=False fonctionne mieux pour les applications de terminal textuelles. absolute a été ajouté pour tenter de résoudre les problèmes d’écart glitchy en mode interactif après réduction de la taille du terminal, mais peut également être utilisé pour des applications terminales. store_max est juste pour le stockage secret, "persistant" de la valeur rows_max; n'utilisez pas explicitement ce paramètre. (Lorsqu'un argument n'est pas passé pour store_max, la modification du contenu de la liste de store_max modifie la valeur par défaut de ce paramètre. Par conséquent, le stockage persistant.)

Portabilité: Désolé, cela ne fonctionne pas dans IDLE, mais cela fonctionne >> VERY COOL << en mode interactif dans un terminal (console) qui reconnaît les séquences d'échappement ANSI. Je n'ai testé cela qu'avec Ubuntu 13.10 en utilisant Python 3.3 dans gnome-terminal. Je ne peux donc que supposer que la portabilité dépend de Python 3.3 (pour la fonction shutil.get_terminal_size() pour des résultats BEST) et de la reconnaissance ANSI. La fonction print(...) est Python 3. Je l’ai également testée avec un simple jeu de terminal Tic Tac Toe à base de texte (application).

Utilisation en mode interactif: Copiez et collez d'abord la fonction copy(...) en mode interactif pour voir si elle fonctionne pour vous. Si tel est le cas, placez la fonction ci-dessus dans un fichier nommé clear.py. Dans le terminal, lancez python, avec 'python3'. Entrer:

>>> import sys
>>> sys.path
['', '/usr/lib/python3.3', ...

Maintenant, déposez le fichier clear.py dans l’un des répertoires path de la liste afin que Python puisse le trouver (ne remplacez aucun fichier existant). A utiliser facilement à partir de maintenant:

>>> from clear import clear
>>> clear()
>>> print(clear.__doc__)
clear(rows=-1, rows_max=None)
clear(0, -1) # Restore auto-determining rows_max
clear(calling_line=False) # Don't clear calling line
clear(absolute=5) # Absolutely clear out to 5 rows up

Utilisation dans une application de terminal: Placez la fonction copy(...) dans un fichier nommé clear.py dans le même dossier que votre fichier main .py. Voici un exemple de travail abstrait (squelette) tiré d'une application de jeu Tic Tac Toe (exécuté à partir de l'invite du terminal: python3 tictactoe .py):

from os import linesep

class TicTacToe:    
    def __init__(self):
        # Clear screen, but not calling line
        try:
            from clear import clear
            self.clear = clear
            self.clear(calling_line=False)
        except ImportError:
            self.clear = False
        self.rows = 0    # Track printed lines to clear

        # ...
        self.moves = [' '] * 9

    def do_print(self, *text, end=linesep):
        text = list(text)
        for i, v in enumerate(text[:]):
            text[i] = str(v)
        text = ' '.join(text)
        print(text, end=end)
        self.rows += text.count(linesep) + 1

    def show_board(self):
        if self.clear and self.rows:
            self.clear(absolute=self.rows)
        self.rows = 0
        self.do_print('Tic Tac Toe')
        self.do_print('''   |   |
 {6} | {7} | {8}
   |   |
-----------
   |   |
 {3} | {4} | {5}
   |   |
-----------
   |   |
 {0} | {1} | {2}
   |   |'''.format(*self.moves))

    def start(self):
        self.show_board()
        ok = input("Press <Enter> to continue...")
        self.moves = ['O', 'X'] * 4 + ['O']
        self.show_board()
        ok = input("Press <Enter> to close.")

if __== "__main__":
    TicTacToe().start()

Explication: do_print(...) à la ligne 19 est une version de print(...) nécessaire pour savoir combien de nouvelles lignes ont été imprimées (self.rows). Sinon, vous devriez self.rows += 1 partout où vous appelez print(...) dans tout le programme. Ainsi, chaque fois que le tableau est redessiné en appelant show_board(), le tableau précédent est effacé et le nouveau tableau est imprimé exactement où il devrait être. Remarquez que self.clear(calling_line=False) sur la ligne 9 pousse fondamentalement tout ce qui est RELATIVE vers le bas du terminal, mais n’efface pas la ligne d’appel initiale. En revanche, self.clear(absolute=self.rows) sur la ligne 29 efface absolument toute la distance self.rows vers le haut, plutôt que de simplement pousser tout vers le haut par rapport au bas du terminal.

Utilisateurs Ubuntu avec Python 3.3: Mettez #!/usr/bin/env python3 sur la toute première ligne du fichier tictactoe.py. Cliquez avec le bouton droit sur le fichier tictactoe.py => Propriétés => Onglet Autorisations => Vérifier l’exécution: Autoriser l’exécution du fichier en tant que programme. Double-cliquez sur le fichier => Cliquez sur le bouton Exécuter dans un terminal. Si le répertoire actuel d'un terminal ouvert est celui du fichier tictactoe.py, vous pouvez également démarrer le fichier avec ./tictactoe.py.

2
JD Graham

Vous pouvez déchirer la base de données terminfo, mais les fonctions pour le faire sont dans curses de toute façon.

2

La réponse acceptée est une bonne solution. Le problème, c’est que jusqu’à présent, il ne fonctionne que sous Windows 10, Linux et Mac. Oui Windows (connu pour son manque de support ANSI)! Cette nouvelle fonctionnalité a été mise en œuvre sous Windows 10 (et supérieur), ce qui inclut la prise en charge ANSI, bien que vous deviez l'activer. Cela effacera l'écran de manière multiplateforme:

import os

print ('Hello World')
os.system('') 
print ("\x1B[2J")

Sur tout ce qui est en dessous de Windows 10, cela retourne cependant ceci:

[2J

Cela est dû au manque de prise en charge ANSI sur les versions précédentes de Windows. Cela peut toutefois être résolu en utilisant le module colorama . Cela ajoute la prise en charge des caractères ANSI sous Windows:

Les séquences de caractères d'échappement ANSI ont longtemps été utilisées pour produire du texte de terminal coloré et le positionnement du curseur sous Unix et Mac. Colorama effectue également ce travail sous Windows en encapsulant stdout, en supprimant les séquences ANSI trouvées (qui apparaissent sous forme de gobbledygook dans la sortie) et en les convertissant en appels Win32 appropriés pour modifier l'état du terminal. Sur d'autres plateformes, Colorama ne fait rien.

Donc, voici une méthode multi-plateforme:

import sys

if sys.platform == 'win32':
    from colorama import init
    init()

print('Hello World')

print("\x1B[2J")

Ou print(chr(27) + "[2J") utilisé au lieu de print("\x1B[2J").


@poke answer est très peu sûr sur Windows, oui ça marche mais c'est vraiment un bidouillage. Un fichier nommé cls.bat ou cls.exe dans le même dictionnaire que le script entrera en conflit avec la commande et exécutera le fichier à la place de la commande, créant ainsi un risque énorme pour la sécurité.

Une méthode permettant de minimiser les risques pourrait consister à modifier l'emplacement où la commande cls est appelée:

import os
os.system('cd C:\\Windows|cls' if os.name == 'nt' else 'clear')

Ceci changera le C urrant D ictionary en C:\Window (la barre oblique inversée est importante ici) puis s'exécutera. C:\Windows est toujours présent et nécessite des autorisations d'administration pour y écrire, ce qui en fait un outil idéal pour exécuter cette commande avec un risque minimal. Une autre solution consiste à exécuter la commande via PowerShell au lieu de l'invite de commande, car celle-ci a été sécurisée contre de telles vulnérabilités. 

Il existe également d'autres méthodes mentionnées dans cette question: Effacer l'écran dans Shell qui peuvent également être utiles.

1
Simon

Il suffit d'utiliser:

print("\033c")

Cela effacera la fenêtre du terminal.

1
Alex Hawking

python -c "from os import system; system('clear')"

1
Dyno Fu

vous pouvez faire le vôtre. cela ne dépendra pas de votre terminal ni du type de système d'exploitation.

def clear(num):
    for i in range(num): print 

clear(80)
print "hello"
1
ghostdog74

Cela effacera 25 nouvelles lignes:

def clear():
    print(' \n' * 25)

clear()

J'utilise Eclipse avec pydev. J'aime mieux la solution newline que le pour les numéros dans la plage . La boucle pour émet des avertissements, alors que la nouvelle ligne à imprimer ne le fait pas .. Si vous souhaitez spécifier le nombre de nouvelles lignes dans la commande clear, essayez cette variation.

def clear(j):
    print(' \n' * j)

clear(25)
1
B-Rell

Si tout ce dont vous avez besoin est d'effacer l'écran, c'est probablement assez bien. Le problème est qu’il n’existe même pas une solution 100% multiplate-forme pour toutes les versions de Linux. Le problème est que les implémentations du terminal supportent toutes des choses légèrement différentes. Je suis à peu près sûr que «clair» fonctionnera partout. Mais la réponse la plus "complète" consiste à utiliser les caractères de contrôle xterm pour déplacer le curseur, mais cela nécessite xterm lui-même.

Sans en savoir plus sur votre problème, votre solution semble assez bonne.

0
Falmarri

Pour Windows, sur la ligne de commande de l'interpréteur uniquement (pas l'interface graphique)! Tapez simplement: (N'oubliez pas d'utiliser une bonne indentation avec python): 

import os
def clear():
    os.system('cls')

Chaque fois que vous tapez clear() sur le shell (ligne de commande), l’écran de celui-ci sera effacé. Si vous quittez le shell, vous devez refaire ce qui précède pour le refaire lorsque vous ouvrez un nouveau shell Python (ligne de commande).

Note: Peu importe la version de Python que vous utilisez, explicitement (2.5, 2.7, 3.3 et 3.4).

0
Riyad El-Laithy

Voici un moyen peut-être ringard d'effacer l'écran, mais celui qui fonctionnera sur toutes les plates-formes que je connais est la suivante:

for i in xrange(0,100):
    print ""
0
Ben

Sous Windows, vous pouvez utiliser:

>>> import os
>>> clear = lambda: os.system('cls')
>>> clear()

Je le ferais de cette façon pour que ça ressemble plus à bash:

Créez simplement un fichier nommé .pythonstartup dans le répertoire personnel et utilisez la réponse de poke dans une fonction.

Sous Linux:

echo "from subprocess import call
def clear(int=None):  
    call('clear')
    if int == 0:
       exit()
clear()" >> $HOME/.pythonstartup ; export PYTHONSTARTUP=$HOME/.pythonstartup ; python

Vous pouvez ajouter export PYTHONSTARTUP=$HOME/.pythonstartup à votre fichier ./bashrc

Puisque ce qui me préoccupe, c'est l'espace. un appel à la fonction n'affichera pas la description de l'interpréteur python au démarrage, mais vous pouvez supprimer clear() pour la conserver.

L'utiliser comme une fonction normale devrait faire l'affaire sans imprimer le statut de sortie:

>>> clear()

Si vous transmettez l’argument 0 à la fonction, l’écran sera effacé et la sortie réussie pour que vous puissiez continuer à utiliser le shell dans un écran vierge.

>>> clear(0)
0
DarkXDroid