Configurazione di cartelle e importazione di moduli in Python

0

Sto costruendo un'app per automatizzare alcuni processi che sono fastidiosi da fare a mano (cercare in un file, prendere certe informazioni da un file, costruire un altro file con quelle informazioni).

Il mio progetto ha tre parti principali: app.py, che parla all'utente e utilizza webpy per creare un'interfaccia semplice; maker.py, che contiene un insieme di funzioni che fanno il sollevamento pesante; e una cartella di modelli html. C'è anche una cartella statica, che è dove l'applicazione mette i risultati del suo duro lavoro.

L'unico modo per far funzionare questo casino è se app.py e maker.py si trovano nella stessa cartella. Questo non mi piace per il modo in cui i vari tutorial mi hanno detto di configurare le mie cartelle, però. Se non sono nella stessa cartella, ottengo errori come "nessun modulo chiamato maker". Un altro problema è che non riesco a vedere alcuna buona ragione per cui la classe FragmentMaker possa esistere del tutto. Perché non posso avere un file pieno di funzioni e solo importare l'intera cosa così com'è?

Qual è il modo migliore per configurare le cartelle per questo tipo di progetto? Maker.py e app.py sono presenti in diverse cartelle? In tal caso, come faccio a importare maker.py in modo da poter usare il codice che ho inserito?

Il lato web, app.py:

import web
from maker import FragmentMaker #can't make this work

urls = ('/upload', 'Upload',
        '/make_link', 'Make_Link'
)

app = web.application(urls, globals())
render = web.template.render('templates/')

maker = FragmentMaker() #this doesn't work either


class Upload:
    def GET(self):
        return render.upload_form()


    def POST(self):
        x = web.input(myfile={})
        filename = x['myfile'].filename
        input_file = x['myfile'].file # returns a file-like object
        if '.docx' in filename: #Runs the docx side of fragment maker
            E_supinfo = maker.makeList(input_file)
            maker.WriteFrag(E_supinfo)
        elif '.csv' in filename: #Runs for everything else
            Other_supinfo = maker.ProcessCSV(input_file)
            maker.WriteFrag(Other_supinfo)
        else: #For unsupported file types
            return render.error_page(filename)
        return render.upload_confirm(filename)

class Make_Link:
    def GET(self):
        return render.make_link('NONE')
    def POST(self):
        instring = web.input(accession = 'NONE')
        E_Link = maker.makeLink(instring.accession)
        return render.make_link(E_Link)

if __name__ == "__main__":
app.run()

E questo è maker.py, più o meno:

import a bunch of useful things other people have built

class FragmentMaker: #does '(object)' need to be in here?
    def __init__(self):
        self.joy = "service is my only joy" #do I need a variable here? Nothing uses this.

    def Thing1(self, stuff_for_thing1):
        useful code here.

    def ProcessCSV(self, other): 
        more code that works

    def makeLink(self, acnum): 
        code here

    def makeList(docname): # does 'self' have to be in these?

        E_List = Thing1(docname) #calling a function from inside another function is ok, right?

        code: then a miracle happens.

... e così via.

la mia struttura di file:

makefrag
|-bin
    app.py
|-docs
    empty for now
|-Fragment_Maker
    __init__.py
    maker.py
|-static
    results go here
|-templates
    html files here
|-tests
    all sorts of random test files and code in here
__init__.py
    
posta JBWeld 23.04.2015 - 16:00
fonte

1 risposta

1

Non posso commentare così invece ti risponderò o ti guiderò lì con domande retoriche:

In primo luogo, come intendi lanciare e utilizzare questo programma? Stai creando un pacchetto python usando __init __. Py's ma stai eseguendo un modulo (bin / app.py) all'interno del pacchetto come __main__. Questa non è una configurazione tipica.

Hai intenzione di importare questo tuo pacchetto in qualche altro script python? Forse non hai bisogno di un pacchetto e puoi usare alcuni script. Generalmente tutti i file python relativi ad alcune funzioni si trovano in un pacchetto coesivo (forse non hai bisogno di quel __init __. Py di livello superiore).

Intendevi che bin / app.py fosse eseguibile dal momento che sembra che sia il tuo unico uso? Aggiungi un comando di esecuzione #!/usr/bin/env python all'inizio del file e IMO crea il file chiamato app ed eseguibile $ chmod +x bin/app .

Sarebbe bello google come Python trova i moduli, come costruire un pacchetto e come funzionano PYTHONPATH e sys.path di env. Se il nome del tuo modulo non lo fa su sys.path o è relativo alla tua directory corrente, python non lo troverà. Ho aggiunto alcuni collegamenti di seguito.

Se non intendi usare una meccanica del pacchetto python potresti semplicemente ( answer ) eseguire un sys.path.append(os.path.join(os.getcwd(), 'Fragment_Maker')) o sys.path.append(os.path.join(os.dirname(__file__), '..', 'Fragment_Maker')) prima del tuo import maker , a seconda di come intendi lanciare la tua applicazione. Altrimenti la tua domanda non può essere risolta senza le supposizioni di cui sopra (ad esempio potresti voler mettere la tua app per script python al massimo livello, mantenere Fragment_Maker un pacchetto, eseguire un from Fragment_Maker import maker ), ma sicuramente puoi ora scoprilo con queste risorse:

risposta data 07.05.2015 - 00:34
fonte

Leggi altre domande sui tag