¿Por qué es un objeto de conjunto almacena como un frozenset y un objeto de lista como un par de valores?

Ch3steR:

Vi un post donde se menciona "Uso func.__code__.co_constsde todas las constantes definidas en la función" .

def func():
    return 1 in {1,2,3}
func.__code__.co_consts
(None, 1, frozenset({1, 2, 3}))

¿Por qué le devolvió una frozenset?

def func():
    return 1 in [1,2,3]
func.__code__.co_consts
(None, 1, (1,2,3))

¿Por qué se devuelve un tuplelugar de una lista? Cada objeto de regresar de __code__.co_constses inmutable . ¿Por qué están hechas las constantes mutable inmutable ? ¿Por qué el primer elemento de la tupla devuelta siempre None?

Sven Marnach:

Todos los objetos de co_constsson constantes, es decir que son inmutables. Usted no debe ser capaz de, por ejemplo, anexados a una lista que aparece como un literal en el código fuente y por lo tanto modificar el comportamiento de la función.

El compilador suele representar literales lista enumerando todas las constantes individuales que aparecen en la lista:

>>> def f():
...     a = [1, 2, 3]
...     return 1 in a
... 
>>> f.__code__.co_consts
(None, 1, 2, 3)

Mirando el código de bytes de esta función se puede observar que la función crea una lista en tiempo de ejecución cada vez que se ejecuta la función:

>>> dis.dis(f)
  2           0 LOAD_CONST               1 (1)
              2 LOAD_CONST               2 (2)
              4 LOAD_CONST               3 (3)
              6 BUILD_LIST               3
              8 STORE_FAST               0 (a)

  3          10 LOAD_CONST               1 (1)
             12 LOAD_FAST                0 (a)
             14 COMPARE_OP               6 (in)
             16 RETURN_VALUE

Creación de una nueva lista se requiere, en general, debido a que la función puede modificar o devolver la lista definida por el literal, en cuyo caso se necesita para operar en un nuevo objeto de la lista cada vez que se ejecuta el Funciton.

En otros contextos, la creación de un nuevo objeto de lista es un desperdicio, sin embargo. Por esta razón, optimizador mirilla de Python puede reemplazar la lista con una tupla, o un conjunto con una frozen_set, en ciertas situaciones en que se sabe que son seguros. Una de estas situaciones es cuando la lista o conjunto literal sólo se utiliza en una expresión de la forma x [not] in <list_literal>. Otra de tales situación es cuando un literal lista se utiliza en un forbucle.

El optimizador mirilla es muy simple. Sólo mira a una expresión a la vez. Por esta razón, no puede detectar que esta optimización estaría a salvo en mi definición de farriba, que es funcionalmente equivalente a su ejemplo.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=298805&siteId=1
Recomendado
Clasificación