2017-10-19 37 views
1

J'essaie d'écrire un script Python qui permet à l'utilisateur de basculer entre stdin/stdout et les fichiers pour l'entrée/sortie. Mais je ne sais pas si ma mise en œuvre est correcte:Comment faire pour résumer stdin/stdout et les fichiers?

#!/usr/bin/python3 

import fileinput 
import sys 

from contextlib import contextmanager 
from contextlib import redirect_stdout 


def foo(file): 
    return ''.join([line for line in file]) 


@contextmanager 
def run(input_file, output_file): 
    stdin = '-' if input_file is None else input_file 
    stdout = sys.stdout if output_file is None else open(output_file, 'w') 
    with fileinput.input(stdin) as stdin, stdout: 
     with redirect_stdout(stdout): 
      print(foo(stdin)) 
  1. est le code de gestion des ressources correctement?
  2. Comment gérer correctement le codage de caractères? J'aimerais tout avoir en utf-8.
  3. Y a-t-il place à amélioration dans le code ci-dessus?

Répondre

1

Je pense que vous devriez faire de cette façon. Vous n'avez pas besoin de faire run() lui-même un @contextmanager - tout ce qu'il faut faire est d'utiliser un (ou plus, et les deux fileinput.input et redirect_stdout sont déjà ceux). Je ne suis pas sûr pourquoi vous utilisez fileinput.input car il semble y avoir un seul fichier d'entrée impliqué.

from contextlib import redirect_stdout 
import fileinput 
import sys 

def foo(file): 
    return ''.join([line for line in file]) 

def run(input_file, output_file): 
    stdin = '-' if input_file is None else input_file 
    stdout = sys.stdout if output_file is None else open(output_file, 'w') 
    with fileinput.input(stdin) as stdin, redirect_stdout(stdout): 
     print(foo(stdin)) 

run('input.txt', 'output.txt') 
run('input.txt', None) 
+0

Merci pour l'info. J'utilise 'fileinput' car il pourrait y avoir plus d'un fichier d'entrée. L'objectif principal est de rendre le script canalisable. Je ne suis pas sûr de comprendre votre commentaire sur '@ contextmanager'. Voulez-vous dire qu'avec l'implémentation actuelle, je n'ai pas besoin de '@ contextmanager'? Et aussi s'il vous plaît commenter sur l'encodage de caractères? – Rad

+0

Je voulais dire que puisque fileinput.input() et redirect_stdout() sont déjà tous les deux des gestionnaires de contextes, vous n'avez pas non plus besoin de faire aussi un 'run()'. En ce qui concerne l'encodage, si 'stdout' n'est pas redirigé, vous pouvez avoir un problème en fonction de l'encodage par défaut de' sys.stdout' pour votre système d'exploitation. Pour les fichiers, vous devrez peut-être utiliser ['codecs.open()'] (https://docs.python.org/3/library/codecs.html#codecs.open) pour éviter les problèmes d'encodage lors de la lecture et de l'écriture de données à partir de/à eux en fonction de ce qu'ils contiennent. Au lieu de poser des questions hypothétiques ici, pourquoi ne pas essayer de l'exécuter et de voir. – martineau