2012-10-06 8 views
6
def A(): 
    def B(): 
     #do something 

a = A() 
a.B() 

¿Por qué no es posible lo anterior (un código tan simple) en Python? ¿Existe una solución "pitonica" (legible, no sorprendente, no hacky) que no convierta a A() en una clase?¿Por qué Python no puede acceder a una subfunción desde el exterior?

Editar 1: Lo anterior me fue explicado que B es local para A, por lo tanto, solo existe mientras A se esté evaluando. Entonces, si lo hacemos global (y no lo sobreescribamos), entonces, ¿por qué no funciona?

def A(): 
    def B(): 
     #do something 
    return A() 

a = A() 
a.B() 

Dice que está devolviendo un objeto 'NoneType'.

Respuesta

7

Porque una definición de función simplemente crea un nombre en el espacio de nombres local. Lo que está haciendo no es diferente de:

def f(): 
    a = 2 

y luego preguntarse por qué no se puede acceder desde fuera a la función. Los nombres enlazados dentro de una función son locales para la función.

Además, su código propuesto es extraño. cuando lo hace a = f(), está configurando un valor de retorno de la función. Su función no devuelve nada, por lo que no puede esperar acceder a nada a través del valor de retorno. Es posible devolver la función interna directamente:

def f(): 
    def g(): 
     return "blah" 
    return g 

>>> func = f() 
>>> func() 
'blah' 

Y esto de hecho puede ser útil. Pero no hay una forma genérica de acceder a las cosas dentro de la función desde afuera, excepto modificando las variables globales (que generalmente es una mala idea) o devolviendo los valores. Así funcionan las funciones: toman entradas y devuelven salidas; ellos no ponen sus entrañas a disposición de la palabra externa.

5

Para llamar a B con la sintaxis desea, utilice:

def A(): 
    def B(): 
     print("I'm B") 
    A.B = B 
    return A 

a = A() 
a.B() 
A.B() 
+0

Por desgracia, es inútil, ya que para inicializar 'A.B' es necesario llamar' A() 'al menos una vez. :( – prokher

+1

@prokher es necesario llamar a A para incluso crear una función anidada. Y será una función diferente cada vez que llame a A. Esa es la única razón para tener una función anidada en primer lugar. –

Cuestiones relacionadas