Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

257
Vistas
¿Reemplazando la funcionalidad del analizador de Python?

En primer lugar, quiero mencionar que sé que esta es una idea horrible y que no debería hacerse. Mi intención es principalmente la curiosidad y aprender las entrañas de Python, y cómo 'hackearlas'.

Me preguntaba si es posible cambiar lo que sucede cuando, por ejemplo, usamos [] para crear una lista. ¿Hay alguna manera de modificar el comportamiento del analizador para, por ejemplo, hacer que ["hello world"] llame a print("hello world") en lugar de crear una lista con un elemento?

Intenté encontrar documentación o publicaciones sobre esto, pero no pude hacerlo.

A continuación se muestra un ejemplo de cómo reemplazar el dictado incorporado para usar una clase personalizada:

 from __future__ import annotations from typing import List, Any import builtins class Dict(dict): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.__dict__ = self def subset(self, keys: List[Any]) -> Dict: return Dict({key: self[key] for key in keys}) builtins.dict = Dict

Cuando se importa este módulo, reemplaza el dict incorporado con la clase Dict . Sin embargo, esto solo funciona cuando llamamos directamente a dict() . Si intentamos usar {} , se recurrirá a la implementación integrada del dict base:

 import new_dict a = dict({'a': 5, 'b': 8}) b = {'a': 5, 'b': 8} print(type(a)) print(type(b))

Rendimientos:

 <class 'py_extensions.new_dict.Dict'> <class 'dict'>
over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

[] y {} se compilan en códigos de operación específicos que devuelven específicamente una list o un dict , respectivamente. Por otro lado list() y dict() se compilan en bytecodes que buscan variables globales para list y dict y luego las llaman como funciones:

 import dis dis.dis(lambda:[]) dis.dis(lambda:{}) dis.dis(lambda:list()) dis.dis(lambda:dict())

devuelve (con algunas nuevas líneas adicionales para mayor claridad):

 3 0 BUILD_LIST 0 2 RETURN_VALUE 5 0 BUILD_MAP 0 2 RETURN_VALUE 7 0 LOAD_GLOBAL 0 (list) 2 CALL_FUNCTION 0 4 RETURN_VALUE 9 0 LOAD_GLOBAL 0 (dict) 2 CALL_FUNCTION 0 4 RETURN_VALUE

Por lo tanto, puede sobrescribir lo que devuelve dict() simplemente sobrescribiendo el dict global, pero no puede sobrescribir lo que devuelve {} .

Estos códigos de operación están documentados aquí . Si se ejecuta el código de operación dict , obtienes un dictado, no hay forma de evitarlo. Como ejemplo, aquí está la implementación de BUILD_MAP en CPython, que llama a la función _PyDict_FromItems . No analiza ningún tipo de clases definidas por el usuario, sino que crea específicamente una estructura C que representa un dict de Python.

Es posible en al menos algunos casos manipular el código de bytes de python en tiempo de ejecución. Si realmente desea hacer que {} devuelva una clase personalizada, supongo que podría escribir algún código para buscar el código de operación BUILD_MAP y reemplazarlo con los códigos de operación apropiados. Aunque esos códigos de operación no son del mismo tamaño, probablemente haya que hacer algunos cambios adicionales.

over 4 years ago · Santiago Trujillo Denunciar

0

El módulo ast es una interfaz para el árbol de sintaxis abstracta de Python que se crea después de analizar el código de Python.
Es posible reemplazar el dict literal ( {} ) con una llamada de dict modificando el árbol de sintaxis abstracta del código de Python.

 import ast import new_dict a = dict({"a": 5, "b": 8}) b = {"a": 5, "b": 8} print(type(a)) print(type(b)) print(type({"a": 5, "b": 8})) src = """ a = dict({"a": 5, "b": 8}) b = {"a": 5, "b": 8} print(type(a)) print(type(b)) print(type({"a": 5, "b": 8})) """ class RewriteDict(ast.NodeTransformer): def visit_Dict(self, node): # don't replace `dict({"a": 1})` if isinstance(node.parent, ast.Call) and node.parent.func.id == "dict": return node # replace `{"a": 1} with `dict({"a": 1}) new_node = ast.Call( func=ast.Name(id="dict", ctx=ast.Load()), args=[node], keywords=[], type_comment=None, ) return ast.fix_missing_locations(new_node) tree = ast.parse(src) # set parent to every node for node in ast.walk(tree): for child in ast.iter_child_nodes(node): child.parent = node RewriteDict().visit(tree) exec(compile(tree, "ast", "exec"))

producción;

 <class 'new_dict.Dict'> <class 'dict'> <class 'dict'> <class 'new_dict.Dict'> <class 'new_dict.Dict'> <class 'new_dict.Dict'>
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda