Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Comment faire pour avoir le bon chemin absolu

+3 votes

Ce script fonctionne correctement mais quand le lance le script depuis la ligne de commande windows ou bien en faisant appel a un raccourci dans le task manager windows ( tache windows) j'obtiens une erreur a cause des chemins d'acces au fichier csv.

Alors que quand le le lance depuis IDLE ou Pycharm par exemple cela fonctionne parfaitement.

La ligne de commande que j'utilise est la suivante:

py -2.7 "C:\Users\bob\Google Drive\pycharmpoject\fluxupdate\ajoutdata.py"

et j'obtiens cette erreur:

IOError:[Errno 2] No such file or directory: 'C:\Users\source_csv\drop\drop-2015-07-09.csv

import csv
import datetime
import shutil
import os

#Declaration du jour

jour = datetime.date.today()

InFile  = os.path.abspath('../source_csv/drop-'+str(jour)+'.csv')
OutFile = os.path.abspath('../source_csv/drop_updated-'+str(jour)+'.csv')

#ajout des columns necessaires

with open(InFile, 'r') as csvinput:
    with open(OutFile, 'wb') as csvoutput:
        writer = csv.writer(csvoutput, lineterminator='\n')
        reader = csv.reader(csvinput, delimiter=",")
        '''next(reader)'''

         all = []
         row = next(reader)
         for row in reader:

            if float(row[6]) < 20:
                row.append(float(row[6])*(0.88*1.53))
                row.append(2.99)
            elif float(row[6]) < 40:
                row.append(float(row[6])*(0.88*1.40)-6.99)
                row.append(7.99)
            else:
                row.append(float(row[6])*(0.88*1.30)-29.99)
                row.append(29.99)

            all.append(row)

        for row in reader:
            row.append(row)
            all.append(row)

        writer.writerow( ('name','description') )
        writer.writerows(all)
demandé 10-Jul-2015 par Andronaute

1 Réponse

+7 votes

Le probleme vient de ces lignes :

InFile  = os.path.abspath('../source_csv/drop-'+str(jour)+'.csv')
OutFile = os.path.abspath('../source_csv/drop_updated-'+str(jour)+'.csv')

Tes '../' sont relatif par rapport au répertoire depuis lequel tu lances ton script.

Tu peux récupérer le répertoire courant de ton script avec

import os
script_path = os.path.dirname(os.path.realpath(__file__))

Que tu pourras ensuite concaténer a ton path, du genre :

InFile  = os.path.abspath(script_path+'../source_csv/drop-'+str(jour)+'.csv')

Au passage, une maniere plus élégante de le faire serait :

InFile = os.path.abspath(os.path.join(script_path, '..', 'source_csv',' drop-{jour}-.csv'.format(jour = jour)))

Je te renvois vers la doc de dirname et realpath pour le détail de ce que font ces deux fonctions.

répondu 10-Jul-2015 par jc (2,704 points)

Une précision, vu qu'il semble que l'op est sous windows, et s'il compte distribuer une version gelée (frozen) de son script: __ file __ n'existe pas.

Du coup, il convient de vérifier si le script est gelé, directement depuis la doc de cx_Freeze:

def find_data_file(filename):
if getattr(sys, 'frozen', False):
    # The application is frozen
    datadir = os.path.dirname(sys.executable)
else:
    # The application is not frozen
    # Change this bit to match where you store your data files:
    datadir = os.path.dirname(__file__)

return os.path.join(datadir, filename)

Le lien vers la doc: http://cx-freeze.readthedocs.org/en/latest/faq.html
De mémoire cela fonctionne aussi avec py2exe et pyInstaller

Sympas l'astuce de os.path.dirname(sys.executable), je connaissais pas !

Merci pour cette explication. J'avais en fait déjà testé cette solution de os.path.dirname sans succes ! Je vais refaire un test avec ta solution. En realité j'ai trouvé une solution directement dans le task manger de windows qui permetté d'excuté le script depuis un endroit précisé :)
Merci aussi pour l'astuce du script distribué

...