Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

184
Visualizações
Comportamiento de alcance extraño en python

Considere el siguiente fragmento de código python:

 x = 1 class Foo: x = 2 def foo(): x = 3 class Foo: print(x) # prints 3 Foo.foo()

Como era de esperar, esto imprime 3. Pero, si agregamos una sola línea al fragmento anterior, el comportamiento cambia:

 x = 1 class Foo: x = 2 def foo(): x = 3 class Foo: x += 10 print(x) # prints 11 Foo.foo()

Y, si cambiamos el orden de las dos líneas en el ejemplo anterior, el resultado cambia una vez más:

 x = 1 class Foo: x = 2 def foo(): x = 3 class Foo: print(x) # prints 1 x += 10 Foo.foo()

Me gustaría entender por qué ocurre esto y, de manera más general, comprender las reglas de alcance que causan este comportamiento. De la regla de alcance LEGB, esperaría que ambos fragmentos impriman 3, 13 y 3, ya que hay una x definida en la función foo() .

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

El alcance del bloque de clases es especial. Está documentado aquí :

Una definición de clase es una declaración ejecutable que puede usar y definir nombres. Estas referencias siguen las reglas normales para la resolución de nombres con la excepción de que las variables locales independientes se buscan en el espacio de nombres global. El espacio de nombres de la definición de clase se convierte en el diccionario de atributos de la clase. El alcance de los nombres definidos en un bloque de clase se limita al bloque de clase; no se extiende a los bloques de código de métodos; esto incluye comprensiones y expresiones generadoras, ya que se implementan utilizando un alcance de función.

Básicamente, los bloques de clase no "participan" en la creación/uso de ámbitos adjuntos.

Entonces, en realidad es el primer ejemplo que no funciona como se documenta . Creo que esto es un error real.

EDITAR:

Bien, en realidad, aquí hay más documentación relevante del modelo de datos , creo que todo es consistente con la documentación:

El cuerpo de la clase se ejecuta (aproximadamente) como exec(body, globals(), namespace). La diferencia clave con respecto a una llamada normal a exec() es que el ámbito léxico permite que el cuerpo de la clase (incluidos los métodos) haga referencia a nombres de los ámbitos actual y externo cuando la definición de la clase se produce dentro de una función.

Entonces , los bloques de clase participan en el uso de ámbitos adjuntos, pero para variables libres (como es normal de todos modos). En la primera parte de la documentación que estoy citando, la parte sobre "las variables locales independientes se buscan en el espacio de nombres global" se aplica a las variables que normalmente el compilador marcaría como locales . Entonces, considere este notorio error, por ejemplo:

 x = 1 def foo(): x += 1 print(x) foo()

Lanzaría un error local no vinculado, pero una definición de clase equivalente:

 x = 1 class Foo: x += 1 print(x)

imprimirá 2 .

Básicamente, si hay una declaración de asignación en cualquier parte de un bloque de clase, es "local", pero verificará en el alcance global si hay un local no vinculado en lugar de generar el error UnboundLocal .

Por lo tanto, en su primer ejemplo, no es una variable local, es simplemente una variable libre y la resolución sigue las reglas normales. En los siguientes dos ejemplos, usa una declaración de asignación, marcando x como "local" y, por lo tanto, se buscará en el espacio de nombres global en caso de que no esté vinculado en el local.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda