duda con code.co_vanames y code.co_names

gagsl-py2 en yahoo.com.ar gagsl-py2 en yahoo.com.ar
Vie Abr 11 09:58:35 CEST 2008


En Thu, 10 Apr 2008 16:09:05 -0300, Milton Galo
Patricio Inostroza Aguilera <minoztro en gmail.com>
escribió:

>    He estado trabajando con el bytecode de python y
tengo dudas con
> co_varnames y co_names, de la definicion:
>
> co_names  	tuple of names of local variables
> co_varnames  	tuple of names of arguments and local
variables

De donde sacaste esas definiciones? En
http://docs.python.org/ref/types.html#l2h-143 dice:
"""co_names is a tuple containing the names used by
the bytecode;
co_varnames is a tuple containing the names of the
local variables (starting with the argument names)"""

co_names son los nombres usados *por* el codigo:
nombres de atributos, variables globales, nombres de
funciones, nombres usados en un import...
co_varnames son todas las variables locales, empezando
por los argumentos de la funcion.
Aca va un ejemplo. Es mas complicado que el tuyo
porque si no no se notan las diferencias:

py> def mostrar(co):
...     print co
...     for x in dir(co):
...         if x[:3]=='co_':
...             print x, getattr(co,x)
...
py> def afuera(x, y=1, z='hola'):
...     def adentro(a):
...         global u,v
...         import math
...         b = 2
...         c = b.algo
...         v = x
...         print x, y, v, a, b, otra
...     mostrar(adentro.func_code)
...     c = 'algo'
...     x.atributo = abs(z)
...

(no te fijes en lo que *hacen* las funciones afuera y
adentro porque no tienen el menor sentido; solo estan
para que existan todos los tipos de variables)

Empecemos por ver lo que hay en la funcion adentro:

py> afuera(0)
<code object adentro at 00A31770, file "<stdin>", line
2>
co_argcount 1 <-- 1 argumento, a
co_cellvars () <-- no tiene
co_code ---basura borrada---
co_consts (None, -1, 2) <-- las constantes que se
usaron en el codigo
co_filename <stdin>
co_firstlineno 2
co_flags 19
co_freevars ('y', 'x') <-- las variables libres:
variables que no son locales y pertenecen a un "scope"
externo pero no global.
co_lnotab ---basura borrada---
co_name adentro 
co_names ('math', 'algo', 'v', 'otra') <-- los nombres
referenciados por el codigo que no son variables
locales (excepto math, que sale de un import)
co_nlocals 4 <-- a, math, b, c
co_stacksize 2
co_varnames ('a', 'math', 'b', 'c') <-- tantas como
dice co_nlocals

Notar que w no figura en ningun lado porque no se usa.
Y ahora miremos lo que hay en la funcion afuera:

py> mostrar(afuera.func_code)
<code object afuera at 00A31C80, file "<stdin>", line
1>
co_argcount 3 <-- x,y,z
co_cellvars ('y', 'x') <-- las que la funcion
"adentro" tiene como variables libres
co_code --- basura ---
co_consts (None, <code object adentro at...>, 'algo')
co_filename <stdin>
co_firstlineno 1
co_flags 3
co_freevars ()  <-- no hay, porque esta funcion no
esta contenida dentro de otra. 
co_lnotab --- basura ---
co_name afuera
co_names ('mostrar', 'func_code', 'abs', 'atributo')
<-- todos los nombres usados que no son variables
locales
co_nlocals 5
co_stacksize 3
co_varnames ('x', 'y', 'z', 'adentro', 'c')

> Pondre un ejemplo para que se entienda mejor:
>
> def myfunc(z):
>     x = 10
>     y = 20
>
> si imprimo el co_varnames y co_names me da la
siguiente:
>
> co_varnames = ('z', 'x', 'y')
> co_names = ()
>
> segun entiendo por la definicion z debiera esttar en
co_names.

Ahora deberia quedar claro que, como la funcion no
referencia ningun nombre, co_names esta vacio. Y en tu
otro ejemplo, aparece "a" porque se lo usa como
atributo.

-- 
Gabriel Genellina


      Yahoo! Encuentros.

Ahora encontrar pareja es mucho más fácil, probá el nuevo Yahoo! Encuentros http://yahoo.cupidovirtual.com/servlet/NewRegistration
_______________________________________________
Lista de correo Python-es 
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes





Más información sobre la lista de distribución Python-es