Página 1 de 1

python: Diferencias métodos ejecución, qué elegir

Publicado: 28 Nov 2015, 14:40
por robalo
json.loads json.dumps vs exec srt

p_1: procedimiento exec srt
p_2: procedimiento json.loads json.dumps

Script:

Código: Seleccionar todo

# -*- coding: utf-8 -*-

_json_str = '{"a":{"a1":"a 1","a2":"a 2","a3":"a 3"},"b":{"b1":"b 1","b2":"b 2","b3":"b 3"},"á":"á 0"}'

def p_1(_json_str_1):

    print "------------------------------------------------------------------------------"
    print "Procedimiento 1 exec str"
    print "------------------------------------------------------------------------------"
    print "##### p_1._json_str_1 ## %s ##" % _json_str_1

    exec "_json_1 = " + _json_str_1
    print "##### p_1._json_1 ## %s ##" % _json_1

    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
    print "##### p_1._json_1['a'] ## %s ##" % _json_1['a']
    print "##### p_1._json_1['a'][a2] ## %s ##" % _json_1['a']['a2']
    print "##### p_1._json_1['b'] ## %s ##" % _json_1['b']
    print "##### p_1._json_1['b'][b3] ## %s ##" % _json_1['b']['b3']
    print "##### p_1._json_1['á'] ## %s ##" % _json_1['á']
    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

    _json_str_2 = str(_json_1)
    print "##### p_1._json_str_2 ## %s ##" % _json_str_2

    exec "_json_2 = " + _json_str_2
    print "##### p_1._json_2 ## %s ##" % _json_2

    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
    print "##### p_1._json_2['a'] ## %s ##" % _json_2['a']
    print "##### p_1._json_2['a'][a2] ## %s ##" % _json_2['a']['a2']
    print "##### p_1._json_2['b'] ## %s ##" % _json_2['b']
    print "##### p_1._json_2['b'][b3] ## %s ##" % _json_2['b']['b3']
    print "##### p_1._json_2['á'] ## %s ##" % _json_2['á']
    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

    _json_str_3 = str(_json_2)
    print "##### p_1._json_str_3 ## %s ##" % _json_str_3
    print "------------------------------------------------------------------------------"

def p_2(_json_str_1):

    print "------------------------------------------------------------------------------"
    print "Procedimiento 2 json.loads json.dumps"
    print "------------------------------------------------------------------------------"
    print "##### p_2._json_str_1 ## %s ##" % _json_str_1

    import json

    _json_1 = json.loads(_json_str_1)
    print "##### p_2._json_1 ## %s ##" % _json_1

    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
    print "##### p_2._json_1['a'] ## %s ##" % _json_1['a']
    print "##### p_2._json_1['a'][a2] ## %s ##" % _json_1['a']['a2']
    print "##### p_2._json_1['b'] ## %s ##" % _json_1['b']
    print "##### p_2._json_1['b'][b3] ## %s ##" % _json_1['b']['b3']
    print "##### p_2._json_1[u'á'].encode('utf-8') ## %s ##" % _json_1[u'á'].encode('utf-8')
    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

    _json_str_2 = json.dumps(_json_1)
    print "##### p_2._json_str_2 ## %s ##" % _json_str_2

    _json_2 = json.loads(_json_str_2)
    print "##### p_2._json_2 ## %s ##" % _json_2

    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
    print "##### p_2._json_2['a'] ## %s ##" % _json_2['a']
    print "##### p_2._json_2['a'][a2] ## %s ##" % _json_2['a']['a2']
    print "##### p_2._json_2['b'] ## %s ##" % _json_2['b']
    print "##### p_2._json_2['b'][b3] ## %s ##" % _json_2['b']['b3']
    print "##### p_2._json_2[u'á'].encode('utf-8') ## %s ##" % _json_2[u'á'].encode('utf-8')
    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

    _json_str_3 = json.dumps(_json_2)
    print "##### p_2._json_str_3 ## %s ##" % _json_str_3
    print "------------------------------------------------------------------------------"

p_1(_json_str)
p_2(_json_str)
Resultados:

Código: Seleccionar todo

------------------------------------------------------------------------------
Procedimiento 1 exec str
------------------------------------------------------------------------------
##### p_1._json_str_1 ## {"a":{"a1":"a 1","a2":"a 2","a3":"a 3"},"b":{"b1":"b 1","b2":"b 2","b3":"b 3"},"á":"á 0"} ##
##### p_1._json_1 ## {'a': {'a1': 'a 1', 'a3': 'a 3', 'a2': 'a 2'}, '\xc3\xa1': '\xc3\xa1 0', 'b': {'b1': 'b 1', 'b2': 'b 2', 'b3': 'b 3'}} ##
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
##### p_1._json_1['a'] ## {'a1': 'a 1', 'a3': 'a 3', 'a2': 'a 2'} ##
##### p_1._json_1['a'][a2] ## a 2 ##
##### p_1._json_1['b'] ## {'b1': 'b 1', 'b2': 'b 2', 'b3': 'b 3'} ##
##### p_1._json_1['b'][b3] ## b 3 ##
##### p_1._json_1['á'] ## á 0 ##
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
##### p_1._json_str_2 ## {'a': {'a1': 'a 1', 'a3': 'a 3', 'a2': 'a 2'}, '\xc3\xa1': '\xc3\xa1 0', 'b': {'b1': 'b 1', 'b2': 'b 2', 'b3': 'b 3'}} ##
##### p_1._json_2 ## {'a': {'a1': 'a 1', 'a3': 'a 3', 'a2': 'a 2'}, '\xc3\xa1': '\xc3\xa1 0', 'b': {'b1': 'b 1', 'b2': 'b 2', 'b3': 'b 3'}} ##
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
##### p_1._json_2['a'] ## {'a1': 'a 1', 'a3': 'a 3', 'a2': 'a 2'} ##
##### p_1._json_2['a'][a2] ## a 2 ##
##### p_1._json_2['b'] ## {'b1': 'b 1', 'b2': 'b 2', 'b3': 'b 3'} ##
##### p_1._json_2['b'][b3] ## b 3 ##
##### p_1._json_2['á'] ## á 0 ##
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
##### p_1._json_str_3 ## {'a': {'a1': 'a 1', 'a3': 'a 3', 'a2': 'a 2'}, '\xc3\xa1': '\xc3\xa1 0', 'b': {'b1': 'b 1', 'b2': 'b 2', 'b3': 'b 3'}} ##
------------------------------------------------------------------------------

Código: Seleccionar todo

------------------------------------------------------------------------------
Procedimiento 2 json.loads json.dumps
------------------------------------------------------------------------------
##### p_2._json_str_1 ## {"a":{"a1":"a 1","a2":"a 2","a3":"a 3"},"b":{"b1":"b 1","b2":"b 2","b3":"b 3"},"á":"á 0"} ##
##### p_2._json_1 ## {u'a': {u'a1': u'a 1', u'a3': u'a 3', u'a2': u'a 2'}, u'\xe1': u'\xe1 0', u'b': {u'b1': u'b 1', u'b2': u'b 2', u'b3': u'b 3'}} ##
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
##### p_2._json_1['a'] ## {u'a1': u'a 1', u'a3': u'a 3', u'a2': u'a 2'} ##
##### p_2._json_1['a'][a2] ## a 2 ##
##### p_2._json_1['b'] ## {u'b1': u'b 1', u'b2': u'b 2', u'b3': u'b 3'} ##
##### p_2._json_1['b'][b3] ## b 3 ##
##### p_2._json_1[u'á'].encode('utf-8') ## á 0 ##
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
##### p_2._json_str_2 ## {"a": {"a1": "a 1", "a3": "a 3", "a2": "a 2"}, "\u00e1": "\u00e1 0", "b": {"b1": "b 1", "b2": "b 2", "b3": "b 3"}} ##
##### p_2._json_2 ## {u'a': {u'a1': u'a 1', u'a3': u'a 3', u'a2': u'a 2'}, u'\xe1': u'\xe1 0', u'b': {u'b1': u'b 1', u'b2': u'b 2', u'b3': u'b 3'}} ##
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
##### p_2._json_2['a'] ## {u'a1': u'a 1', u'a3': u'a 3', u'a2': u'a 2'} ##
##### p_2._json_2['a'][a2] ## a 2 ##
##### p_2._json_2['b'] ## {u'b1': u'b 1', u'b2': u'b 2', u'b3': u'b 3'} ##
##### p_2._json_2['b'][b3] ## b 3 ##
##### p_2._json_2[u'á'].encode('utf-8') ## á 0 ##
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
##### p_2._json_str_3 ## {"a": {"a1": "a 1", "a3": "a 3", "a2": "a 2"}, "\u00e1": "\u00e1 0", "b": {"b1": "b 1", "b2": "b 2", "b3": "b 3"}} ##
------------------------------------------------------------------------------
Los tiempos entre los dos procedimientos se puede decir que son similares.

Antes los resultados yo me dacantaría el p_1, más simple y menos engorroso, pero... como veo mucha trajín con el método del p_2 (no sólo en este foro, en muchos foros, webs, blogs,...) es posible que se me escape algo que no veo.

Alguién me puede decir dónde radica la diferencia. Un "Si lo hacen todos o casi todos por algo será" no me vale.

Re: python: Diferencias métodos ejecución, qué elegir

Publicado: 07 Dic 2015, 18:16
por jesus
La filosofía nunca fue mi fuerte :)

A mí siempre me ha gustado lo que se lee más fácil, por eso prefiero "a and b" que "a && b" y cosas así. Así que me decantaría por la opción 2 también.

Y un argumento de peso es que el "exec" está prohibido en Plex, al ser un comando poco seguro. Ese y otros por el estilo, por eso en el servertools se hace esto:

Código: Seleccionar todo

            
# Sustituye el código por otro "Plex compatible"
#exec "from servers import "+serverid
#exec "devuelve.extend("+serverid+".find_videos(data))"
servers_module = __import__("servers."+serverid)
server_module = getattr(servers_module,serverid)
devuelve.extend( server_module.find_videos(data) )
Apuesto a que no es el único sistema que tiene Python embebido y lo prohibe.

Re: python: Diferencias métodos ejecución, qué elegir

Publicado: 07 Dic 2015, 19:57
por robalo
Gracias jesus por contestar.

Estoy contigo en que una palabra siempre es más legible que un síbolo "^, %, ||, &&, etc" pero en el caso de python "and" no funciona igual que "&". "6276 and 256 = 256 ó True", "6276 & 256 = 0 ó False". Para saber si un bit está seteado no nos vale "and", pero vamos, no es el caso del hilo.

Es cierto que Plex no te permite usar "exec" en los "import py". No se si en casos del mismo peso también lo hará. En las pruebas con Plex lo que mejor me ha funcionado ha sido algo como

Código: Seleccionar todo

canal = __import__("channels." + channel, globals(), locals(), ["*"], -1)
pero para los casos de este hilo como

Código: Seleccionar todo

exec "_json_1 = " + _json_str_1
no hay ningún problema.

Reconozco que me has hecho dudar y he vuelto a comprobarlo por si las pruebas en Plex se quedaron en tareas pendientes :)

Gracias otra vez

Re: python: Diferencias métodos ejecución, qué elegir

Publicado: 07 Dic 2015, 21:32
por divadr
Respecto a lo de que "exec" está prohibido en plex, es cierto a medias...

en plex hay muchos comandos prohibidos en el modulo principal ("__init__.py")
pero cuando importas un modulo en el modulo importado si pueden ejecutarse todas esas funciones.

llevo varias semanas trasteando con plex y te puedo asegurar que se puede, por lo menos en Windows y con la ultima versión de plex funciona sin problemas... siempre que esos comandos no se ejecuten en el __init__.py pero en el servertools.py o el launcher.py o en cualquier otro modulo funciona perfectamente

Re: python: Diferencias métodos ejecución, qué elegir

Publicado: 07 Dic 2015, 22:52
por robalo
Pues tienes razón. 'exec "import " + py' lo intenté usar en el __init__ para poder usar la opción "Buscar..." en los canales y terminé usando "get_channel_module()" de servertools. He estado probando 'exec "import " + py' en servertools y en un canal y ha funcionado sin problemas.

Muy buen apunte, muchas gracias.

La versión que uso de Plex sobre Ubuntu no es la última, es la 0.9.9.14

Re: python: Diferencias métodos ejecución, qué elegir

Publicado: 09 Dic 2015, 18:43
por jesus
Sobre Plex no soy neutral...

Lo que puedo decir es que lo que es verdad hoy, puede que deje de serlo en la próxima versión.

Y lo digo porque me ha pasado muchas veces :)

Por no alejarnos del tema de este hilo, a mí me gusta más la solución 2 porque es menos "dinámica" y yo dejé una parte de mi alma en Java donde esas barbaridades tan "dinámicas" no se pueden hacer.

Yo diría que es más optimizable por el intérprete usar una llamada propia del lenguaje que no un "exec", y además añadiría esa preferencia personal mía, para darle más peso a la opción sin "exec", pero no tengo ningún motivo concreto.
robalo escribió:Estoy contigo en que una palabra siempre es más legible que un síbolo "^, %, ||, &&, etc" pero en el caso de python "and" no funciona igual que "&". "6276 and 256 = 256 ó True", "6276 & 256 = 0 ó False". Para saber si un bit está seteado no nos vale "and", pero vamos, no es el caso del hilo.
Estaba pensando en PHP, donde puedes elegir entre poner "if (esto && aquello)" y también "if (esto and aquello)".

Una de las cosas que más me gustan de Python es que el sentido estético es ley, como pasa por ejemplo con las tabulaciones.

Re: python: Diferencias métodos ejecución, qué elegir

Publicado: 09 Dic 2015, 22:51
por robalo
jesus escribió:Estaba pensando en PHP, donde puedes elegir entre poner "if (esto && aquello)" y también "if (esto and aquello)".

Una de las cosas que más me gustan de Python es que el sentido estético es ley, como pasa por ejemplo con las tabulaciones.
Ya me imaginaba algo así :) en python "&&" como que no, al menos conmigo, igual me tiene manía :)
En PHP es casi igual que en Python con la excepción de "&&". En PHP "&&" y "and" se podría decir que son iguales e igual al "and" de Python y "&", en ambos casos, como el que usamos en las calculadoras, los dos funcionan igual :)

Dejando ya este mareo, que lo es, hablemos de estética aunque yo no soy el más indicado para opinar.
Excluyendo las impuesta por el lenguaje, yo no tengo problemas con eso, me adapto casi a lo que sea y tampoco estoy en contra de tema "dinámico", siempre me ha gustado más el "Como" que el "Si". Todo esto lo digo desde mi punto de vista de aficionado y pardillo que es lo que realmente soy :)

Ahora a lo que importa, el hilo.
Me quedo quedo con la 2. Haré todo lo posible para desintoxicarme y añadiré "u","unicode", "decode", etc, o lo que buenamente crea que pueda ser funcional. En HDFull ya opté por esta opción y puede que que algún sitio más. Es lo que se ha venido usando. Para mi es un mareo pero soprtable y por lo que he visto no tengo la exclusividad.