Domanda

Ho un progetto Python in cui io sono con molti file non di codice. Attualmente queste sono tutte le immagini, ma potrebbero usare altri tipi di file in futuro. Quale sarebbe un buon programma per la memorizzazione e riferimento questi file?

Ho considerato solo facendo una cartella "risorse" nella directory principale, ma c'è un problema; Alcune immagini sono utilizzate all'interno di sotto-pacchetti del mio progetto. Memorizzazione di queste immagini che modo porterebbe a accoppiamento, che è uno svantaggio.

Inoltre, ho bisogno di un modo per accedere a questi file, che è indipendente su ciò che la mia directory corrente è.

È stato utile?

Soluzione

Si consiglia di utilizzare libreria pkg_resources che viene fornito con setuptools.

Per esempio, ho fatto un rapido piccolo pacchetto "proj" per illustrare lo schema di organizzazione delle risorse userei:

proj/setup.py
proj/proj/__init__.py
proj/proj/code.py
proj/proj/resources/__init__.py
proj/proj/resources/images/__init__.py
proj/proj/resources/images/pic1.png
proj/proj/resources/images/pic2.png

Si noti come continuo a tutte le risorse in un sottopacchetto separata.

"code.py" mostra come pkg_resources è usato per riferirsi agli oggetti delle risorse:

from pkg_resources import resource_string, resource_listdir

# Itemize data files under proj/resources/images:
print resource_listdir('proj.resources.images', '')
# Get the data file bytes:
print resource_string('proj.resources.images', 'pic2.png').encode('base64')

Se si esegue, si ottiene:

['__init__.py', '__init__.pyc', 'pic1.png', 'pic2.png']
iVBORw0KGgoAAAANSUhE ...

Se è necessario trattare una risorsa come FileObject, uso resource_stream().

Il codice di accesso alle risorse può essere ovunque all'interno della struttura sottopackage del progetto, ha solo bisogno di fare riferimento a subpackage contenente le immagini per nome completo:. proj.resources.images, in questo caso,

Ecco "setup.py":

#!/usr/bin/env python

from setuptools import setup, find_packages

setup(name='proj',
      packages=find_packages(),
      package_data={'': ['*.png']})

Caveat: Per verificare le cose "a livello locale", che è w / o l'installazione del primo pacchetto, dovrete richiamare i vostri script di test dalla directory che ha setup.py. Se siete nella stessa directory di code.py, Python non saprà di pacchetto proj. Quindi le cose come proj.resources non risolveranno.

Altri suggerimenti

Si può sempre avere una cartella separata "risorse" in ogni subpackage che ne ha bisogno, e utilizzare le funzioni os.path per arrivare a questi dai valori __file__ dei vostri sottopacchetti. Per illustrare quello che voglio dire, ho creato il seguente file __init__.py in tre sedi:

c:\temp\topp        (top-level package)
c:\temp\topp\sub1   (subpackage 1)
c:\temp\topp\sub2   (subpackage 2)

Ecco il file __init__.py:

import os.path
resource_path = os.path.join(os.path.split(__file__)[0], "resources")
print resource_path

In c: temp \ lavoro \, creo un app, topapp.py, come segue:

import topp
import topp.sub1
import topp.sub2

Questa respresents l'applicazione che utilizza il pacchetto topp e sottopacchetti. Poi ho eseguito:

C:\temp\work>topapp
Traceback (most recent call last):
  File "C:\temp\work\topapp.py", line 1, in 
    import topp
ImportError: No module named topp

Ecco come previsto. Abbiamo impostato la PYTHONPATH per simulare avere il nostro pacchetto sul percorso:

C:\temp\work>set PYTHONPATH=c:\temp

C:\temp\work>topapp
c:\temp\topp\resources
c:\temp\topp\sub1\resources
c:\temp\topp\sub2\resources

Come si può vedere, i percorsi delle risorse risolti correttamente la posizione del reale (sotto) pacchetti sul percorso.

Aggiornamento: Ecco 's la documentazione relativa py2exe .

@ pycon2009, c'è stata una presentazione su distutils e setuptools. Potete trovare tutti i video qui

Uova e Buildout implementazione in Python - Parte 1

Uova e Buildout implementazione in Python - Parte 2

Uova e Buildout implementazione in Python - Parte 3

In questi video, essi descrivono come includere risorse statiche nel pacchetto. Credo proprio nella parte 2.

Con setuptools, è possibile definire le dipendenze, questo permetterebbe di avere 2 pacchetti che utilizzano risorse dal 3 pacchetto.

setuptools ti dà anche un modo standard di accesso a queste risorse e consente di utilizzare percorsi relativi all'interno dei pacchetti, che elimina la necessità di preoccuparsi di dove sono installati i pacchetti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top