2010-10-17 6 views
3

Ceci est mon premier script python, soyez averti.Y a-t-il une approche plus pythonique à cela?

J'ai assemblé ceci à partir de Dive Into Python, et ça marche très bien. Cependant, puisque c'est mon premier script Python, j'apprécierais des conseils sur la façon dont il peut être amélioré ou des approches qui pourraient mieux embrasser la façon de programmer Python.

import os 
import shutil 

def getSourceDirectory(): 
    """Get the starting source path of folders/files to backup""" 
    return "/Users/robert/Music/iTunes/iTunes Media/" 

def getDestinationDirectory(): 
    """Get the starting destination path for backup""" 
    return "/Users/robert/Desktop/Backup/" 

def walkDirectory(source, destination): 
    """Walk the path and iterate directories and files""" 

    sourceList = [os.path.normcase(f) 
     for f in os.listdir(source)] 

    destinationList = [os.path.normcase(f) 
     for f in os.listdir(destination)] 

    for f in sourceList: 
     sourceItem = os.path.join(source, f) 
     destinationItem = os.path.join(destination, f) 

     if os.path.isfile(sourceItem): 
      """ignore system files""" 
      if f.startswith("."): 
       continue 

      if not f in destinationList: 
       "Copying file: " + f 
       shutil.copyfile(sourceItem, destinationItem) 

     elif os.path.isdir(sourceItem): 
      if not f in destinationList: 
       print "Creating dir: " + f 
       os.makedirs(destinationItem) 

      walkDirectory(sourceItem, destinationItem) 

"""Make sure starting destination path exists""" 
source = getSourceDirectory() 
destination = getDestinationDirectory() 

if not os.path.exists(destination): 
    os.makedirs(destination) 

walkDirectory(source, destination) 
+0

Je dois être en train de le perdre, je ne vois pas le champ Wiki de la communauté dans le formulaire, cela devrait être un wiki communautaire – blu

+0

Il n'y a plus de CW. Il a été retiré. – JoshD

+1

@JoshD: Je n'ai apparemment pas eu le mémo. Je ne mets pas mes en-têtes sur mes rapports TPS, mais je ne suis pas convaincu que ces deux sont liés. – blu

Répondre

6

Comme d'autres mentionné, vous souhaitez probablement utiliser walk à partir du module os intégré. En outre, pensez à utiliser PEP 8 compatible style (pas de chameau mais this_stye_of_function_naming()). Envelopper un code directement exécutable (c'est-à-dire aucune bibliothèque/module) dans un bloc if __name__ == '__main__': ... est également une bonne pratique.

+0

J'ai commencé à regarder le guide de style sur python.org, mais j'ai utilisé Dive Into Python comme point de départ pour la fonctionnalité. Est-ce que Dive Into Python est totalement piraté en termes de syntaxe? – blu

+0

Aussi si je peux, pourquoi le paquet os n'utilise pas "_"? Ex. "isfile", "makedirs", etc – blu

+0

Peu importe, "Les conventions de nommage de la bibliothèque de Python sont un peu un gâchis, donc nous n'obtiendrons jamais cela complètement cohérent", oh man ... – blu

3

Utilisez os.path.walk. Il fait la plupart de la comptabilité pour vous; vous lui donnez juste une fonction visiteur pour faire ce dont vous avez besoin.

Ou, oh putain, on dirait que os.path.walk a été déprécié. Utilisez os.walk puis, et vous obtenez

for r, d, f in os.walk('/root/path') 
    for file in f: 
     # do something good. 
+1

os.path.walk n'est-il pas obsolète en faveur de os.walk? >>> Note Cette fonction est obsolète et a été supprimée en 3.0 en faveur de os.walk(). (à partir du bas de http://docs.python.org/library/os.path.html) – JoshD

+0

Regarde cool, je vais vérifier, merci. – blu

+0

ouais, attrapé moi-même. Je ne peux pas suivre les dépréciations. Merci. –

2

Je recommande d'utiliser os.walk. Il fait ce que vous semblez faire. Il offre une interface agréable à utiliser pour faire ce dont vous avez besoin.

4

Le code

  • n'a pas docstring décrivant ce qu'il fait
  • réinvente la « batterie » de shutil.copytree
  • a une fonction appelée walkDirectory qui ne fait pas ce que son nom l'indique
  • contient get* fonctions qui ne fournissent aucune utilité
    • ces fonctions get embarquent des arguments de haut niveau s plus profond qu'ils ne devraient
  • est bavard obligatoirement (print si vous le vouliez ou non)
+1

Vous avez mélangé dans les plaintes générales sur le style de codage, mais l'a fait de manière non verbeuse, non perturbante. C'est exactement ce que j'attends de réponses de qualité sur SO. (+1) – paprika

+0

Est-ce que shutil.copytree fait vraiment la même chose? "Le répertoire de destination, nommé par dst, ne doit pas déjà exister". Le script que j'ai écrit ne copie pas l'intégralité de la source à chaque fois, il recherche de nouveaux fichiers qui n'ont pas encore été copiés. Est-ce que je manque quelque chose? – blu

+0

Vos autres points sont d'excellents commentaires, merci. – blu

1

La principale chose à rendre les choses plus Pythonic est d'adopter pep8 Python, le guide de style. Il utilise le soulignement pour les fonctions.

Si vous renvoyez une chaîne fixe, par ex. vos fonctions get *, une variable est probablement une meilleure approche. Par cela, je veux dire remplacer votre getSourceDirectory avec quelque chose comme ceci:

source_directory = "/Users/robert/Music/iTunes/iTunes Media/" 

Ajout conditionnel suivant signifie que le code qui est spécifique pour exécuter le module en tant que programme ne soit pas appelé lorsque le module est importé.

if __name__ == '__main__': 
    source = getSourceDirectory() 
    destination = getDestinationDirectory() 

    if not os.path.exists(destination): 
     os.makedirs(destination) 

    walkDirectory(source, destination) 

J'utiliser un bloc try & except, plutôt qu'une condition pour tester si walkDirectory peut fonctionner avec succès.Des choses bizarres peuvent se produire avec de nombreux processus & systèmes de fichiers:

try: 
    walkDirectory(source, destination) 
except IOError: 
    os.makedirs(destination) 
    walkDirectory(source, destination) 

J'ai laissé à la discussion sur l'opportunité d'utiliser la bibliothèque standard. A ce stade de votre voyage en Python, je pense que vous êtes juste après avoir ressenti comment la langue devrait être utilisée en termes généraux. Je ne pense pas connaître les détails de os.walk est vraiment important en ce moment.

Questions connexes