🤝 La pareja «Python + Lua» combina el rico ecosistema de Python con la velocidad y la capacidad de integración de Lua.
A continuación se presentan 3 formas de integración que funcionan con ejemplos, consejos de intercambio de datos y listas de verificación para un inicio rápido.

🔍 Por qué combinar Python y Lua
Python | Lua |
|---|---|
Un mar de bibliotecas: web, IA, datos | Tiempo de ejecución mínimo, fácil de integrar |
Código simple, prototipo rápido | A menudo más rápido en ciclos tight (LuaJIT) |
API/backend, procesamiento de datos | Scripting de motores/juegos, complementos |
🎯 Escenarios típicos
Juegos y simulaciones: servidor/herramientas en Python, lógica de juego en Lua.
Plugins: los usuarios escriben extensiones en Lua, el núcleo en Python.
Automatización: orquestación de Python, scripts de Lua para tareas.
🛠 Tres formas de integración
1) Incorporamos Lua en Python a través de lupa (LuaJIT)
pip install lupaPython → llama a Lua
from lupa import LuaRuntime
lua = LuaRuntime(unpack_returned_tuples=True)
# 1) Obtenemos la función directamente
greet = lua.eval('function(name) return "Hello, " .. name .. "!" end'int(greet("Code")) # ¡Hola, Kodik!
# 2) Trabajar con una tabla como un objeto
Vector = lua.eval('''
function (x, y)
return { x = x or 0, y = y or 0,
len = function(self) return math.sqrt(self.x*self.x + self.y*self.y) end
}
end
''')
v = Vector(3, 4)
print(v.len(v)) # 5.0Lua → llama a Python (retrollamadas)
from lupa import LuaRuntime
lua = LuaRuntime()
def py_log(msg): print("[PY]", msg)
lua.globals().py_log = py_log
lua.execute('py_log("Hello from Lua!")'') # [PY] ¡Saludos desde Lua!
# Pasamos la función Python al algoritmo Lua
lua.execute('''
function apply_twice(fn, x) return fn(fn(x)) end
''')
apply_twice = lua.eval('apply_twice')
print(apply_twice(lambda v: v * 2, 5)) # 20Pros: simple, muy rápido (LuaJIT), llamadas bidireccionales.
Desventajas: dependencia de binarios, matices de tipos.
2) Ejecutar Lua como proceso (subprocess + JSON)
Un método aislado y comprensible para los principiantes: nos comunicamos a través de flujos estándar y serialización.
Script Lua (stdin → stdout)
-- file: worker.lua
local json = require("dkjson") -- или cjson, если доступен
local input = io.read("*a")
local req = json.decode(input)
local result = { sum = req.a + req.b, ok = true }
io.write(json.encode(result))Envoltura de Python
import json, subprocess
payload = json.dumps({"a": 2, "b": 40})
proc = subprocess.run(
["lua", "worker.lua"],
input=payload, text=True, capture_output=True, check=True
)
res = json.loads(proc.stdout)
print(res["sum"]) # 42Pros: independencia de los entornos, fácil depuración/escala. Contras: IPC es más caro que una llamada directa.
3) Avanzado: capa C general / FFI
Adecuado cuando hay un módulo C/C++ existente: Python y Lua se vinculan al mismo código nativo. Para empezar, basta con que el principiante sepa que existe tal camino; más profundo, más tarde.
🔄 Intercambio de datos sin dolor
Qué transmitimos | Cómo transmitimos | Comentario |
|---|---|---|
Números, cadenas, bool | Argumentos de la función (lupa) / JSON | Ten en cuenta que en Lua los números son flotantes por defecto |
Matrices/tablas | Tabla Lua ↔ Python-list/dict | Para estructuras complejas: serialización en JSON/MsgPack |
Datos binarios | Base64 / archivos / memoria compartida | En el esquema de subproceso, es más conveniente usar un archivo/tubería |
Errores frecuentes: tipos flotantes (int vs float), codificación de cadenas (UTF-8!), recursión en estructuras.
🧯 Errores y registro
Excepciones
lupa: el error de Lua generará una excepción de Python: envuelve las llamadas
try/except.subproceso: comprueba
returncodey analizastderr.
Registros
Haz un prefijo de registro común:
[PY]y[LUA].Para subprocess, registra la entrada/salida (recortando las grandes payloads).
💡 Miniexemplo: «reglas» en Lua, servicio en Python
-- rules.lua
return {
discount = function(price)
if price >= 100 then return price * 0.9 end
return price
end
}# service.py
from lupa import LuaRuntime
lua = LuaRuntime()
rules = lua.eval("dofile")("rules.lua")
def final_price(x): return rules["discount"](x)
print(final_price(150)) # 135.0💡 Miniexemplo: mini-RPC a través de JSON
-- rpc.lua (Lua-процесс)
local json = require "dkjson"
local fn = {
hello = function(args) return "Hi, " .. (args.name or "anon") end,
add = function(a,b) return a+b end
}
local req = json.decode(io.read("*a"))
local ok, out = pcall(function()
if req.fn == "add" then return fn.add(req.a, req.b)
else return fn.hello(req) end
end)
io.write(json.encode({ ok = ok, result = out }))# py_rpc.py
import json, subprocess
def call(fn, **kw):
req = json.dumps(dict(fn=fn, **kw))
p = subprocess.run(["lua","rpc.lua"], input=req, text=True,
capture_output=True, check=True)
return json.loads(p.stdout)["result"]
print(call("hello", name="Code"))
print(call("add", a=2, b=40))📚 ¿Quieres profundizar en el tema?
En el anexo Kodik encontrarás tutoriales detallados sobre Python y Lua, ejercicios paso a paso, análisis de errores y práctica cómoda directamente en tu teléfono o navegador.
Y si quieres estar al tanto de las noticias, nuevas características y materiales útiles, suscríbete a nuestro Canal de Telegram. Es acogedor, profesional y con amor por el código ❤️
💬 ¿Qué llevarás a Lua: reglas, configuraciones o cálculos «calientes»?
