2016-03-23 17 views
2

Ich stoße auf etwas Seltsames mit einer Variablen, auf die in anderen Funktionen nach dem Festlegen nicht zugegriffen werden kann. Dies ist eine Datei namens Sellerie Aufgabe html.pyProblem mit dem Python-Variablenbereich im Skript

base_path = '' 

@app.task(bind=True) 
def status(self): 
    """ 
    returns the count of files downloaded and the timestamp of the most recently downloaded file 
    """ 

    num_count = 0 
    latest_timestamp = '' 
    for root, _, filenames in os.walk(base_path): 
     for filename in filenames: 
      file_path = root + '/' + filename 
      file_timestamp = datetime.fromtimestamp(os.path.getctime(file_path)) 
      if latest_timestamp == '' or file_timestamp > latest_timestamp: 
       latest_timestamp = file_timestamp 
      num_count += 1 

@app.task(bind = True) 
def download(self, url='', cl_id=-1): 
    if len(url) == 0 or cl_id < 0: 
     return None 

    base_path = settings.WGET_PATH + str(cl_id) 

    log_paths = { 
     'output' : wget_base_path + '/out.log', 
     'rejected' : wget_base_path + '/rejected.log' 
    } 

    create_files(log_paths) 
    wget_cmd = 'wget -prc --convert-links --html-extension --wait=3 --random-wait --no-parent ' \ 
        '--directory-prefix={0} -o {1} --rejected-log={2} {3}'.\ 
     format(wget_base_path, log_paths['output'], log_paths['rejected'], url) 

    subprocess.Popen(wget_cmd, shell = True) 

Als ich das nennen über

from ingest.task import html 
web_url = 'https://www.gnu.org/software/wget/manual/html_node/index.html' 
ingest = html.download.delay(web_url, 54321) 

der wget Prozess wie erwartet beginnt. Allerdings wird die base_path Parameter am Anfang der Datei nie eingestellt, so, wenn ich rufe status über

status = html.status.delay() 

das base_path Variable ist ein leerer String, trotz status nach download genannt zu werden. Liegt das daran, dass sich diese Aufgaben in einem Skript oder in einer Klasse befinden?

Antwort

4

Da in Funktion download an dieser Linie

base_path = settings.WGET_PATH + str(cl_id) 

Sie schafft nur eine lokale Variable mit Namen base_path. Um dies zu vermeiden, sollten Sie base_path als global deklarieren. Zum Beispiel:

@app.task(bind = True) 
def download(self, url='', cl_id=-1): 
    if len(url) == 0 or cl_id < 0: 
     return None 

    global base_path 
    base_path = settings.WGET_PATH + str(cl_id) 
... 

Von Python docs:

Zu jeder Zeit während der Ausführung gibt es mindestens drei verschachtelte Bereiche, deren Namensräume sind direkt zugänglich:

  • der innerste Umfang, die gesucht wird, enthält zunächst die lokalen Namen
  • Die Bereiche aller umschließenden Funktionen, die beginnend mit dem nächsten umschließenden Bereich gesucht werden, enthalten nicht lokale, aber auch nicht globale Namen
  • die next-to-last Umfang enthält die globalen Namen
  • der äußerste Umfang (Suche zuletzt) ​​des aktuellen Moduls ist der Namespace

Wenn ein Name global deklariert wird, dann werden alle Referenzen eingebauten Namen enthält, und Zuweisungen gehen direkt in den mittleren Bereich, der die globalen Namen des Moduls enthält. Andernfalls sind alle außerhalb des innersten Bereichs gefundenen Variablen schreibgeschützt (ein Versuch, in eine solche Variable zu schreiben, erzeugt einfach eine neue lokale Variable im innersten Bereich, wobei die gleichnamige äußere Variable unverändert bleibt).

+0

Hmm, ok. Danke für die Erklärung. Noch eine weitere Java-Erfahrung stolpert mich mit Python. – Jason