Qual è la relazione tra scope e namespace in Python?

10

In molte risorse ho trovato "scope" e "namespace" sono usati in modo intercambiabile, il che sembra un po 'confuso dal momento che significano cose diverse.

  • L'ambito definisce la regione del codice in cui è disponibile un nome.
  • La regola LEGB definisce il modo in cui i nomi vengono cercati.
  • Namespace è un posto dove cercare i nomi.

Poi ho letto:

  • "i nomi sono associati a uno spazio dei nomi in base a dove sono assegnati ..." (che credo sia l'accordo con gli ambiti in ambito lessicale).
  • Le funzioni "aggiungono un ulteriore livello di spazio dei nomi ai tuoi programmi" [ ref . ] (non aggiungono un ambito locale extra?)
  • "tutti i nomi assegnati all'interno di una definizione di funzione vengono inseriti nell'ambito locale (il file spazio dei nomi associato alla chiamata della funzione). "
  • "ambito globale, ovvero uno spazio dei nomi in cui le variabili create (assegnate) al livello superiore del file del modulo sono attive."

* tutte le citazioni provengono da learning python 5th edition ch17

Gli spazi dei nomi sono in Python il modo in cui vengono implementati gli ambiti? Sono la stessa cosa? Qualcuno può illuminarmi?

    
posta Nikos 15.02.2015 - 16:55
fonte

2 risposte

12

Uno spazio dei nomi è un dizionario, che associa i nomi (come stringhe) ai valori. Quando fai un compito, come a = 1 , stai mutando uno spazio dei nomi. Quando crei un riferimento, come print(a) , Python guarda attraverso un elenco di spazi dei nomi per provare a trovarne uno con il nome come chiave.

Un ambito definisce quali spazi dei nomi verranno esaminati e in quale ordine. L'ambito di ogni riferimento inizia sempre nello spazio dei nomi locale e si sposta verso l'esterno fino a raggiungere lo spazio dei nomi globale del modulo, prima di passare a builtins (lo spazio dei nomi che fa riferimento alle funzioni e alle costanti predefinite di Python, come range e getattr ), che è la fine della linea.

Immagina di avere una funzione denominata inner , nidificata in una funzione globale denominata outer e inner contiene un riferimento a un nome. Python guarda prima nello spazio dei nomi inner . Se il nome non è lì, Python cerca nel namespace outer . Se fallisce, Python prova lo spazio dei nomi global del modulo, poi lo spazio dei nomi builtin , eventualmente lanciando un NameError se il nome non viene trovato.

Quando diciamo x è nel namespace di una funzione, intendiamo che è definito lì, localmente all'interno della funzione. Quando diciamo che x è nell'ambito della funzione, intendiamo che x è nel namespace della funzione o in uno qualsiasi degli spazi dei nomi esterni in cui lo spazio dei nomi della funzione è annidato all'interno.

Ogni qualvolta si definisce una funzione, si crea un nuovo spazio dei nomi e un nuovo ambito. Lo spazio dei nomi è il nuovo hash locale dei nomi. L'ambito è la catena implicita di spazi dei nomi che inizia nel nuovo spazio dei nomi, quindi si fa strada attraverso qualsiasi spazio dei nomi esterno (ambiti esterni), fino allo spazio dei nomi globale (l'ambito globale) e ai builtin.

I termini possono essere usati quasi in modo intercambiabile, ma non è perché significano la stessa cosa; è perché si sovrappongono molto in quello che implicano.

    
risposta data 17.02.2015 - 15:02
fonte
3

C'è un eccellente articolo sugli spazi dei nomi Python qui . Per citare la parte rilevante per rispondere alla tua domanda sul riferimento tra scope e namespace:

A scope refers to a region of a program from where a namespace can be accessed without a prefix.

Ad esempio, immagina un semplice programma di lancio:

import random  # 'random' is in module namespace

def roll(sides=6):  # 'roll' is in module namespace, 'sides' is in roll's
    return random.randint(1, sides)  # both 'random' and 'sides' are in scope here

# but sides can't be accessed out here 

roll ha il proprio spazio dei nomi , ma i nomi nello spazio dei nomi del modulo sono anche nell'ambito .

    
risposta data 15.02.2015 - 18:37
fonte

Leggi altre domande sui tag