es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

TypeError: getattr(): el nombre del atributo debe ser una cadena.

Necesito organizar la salida como un botón en un bot de Telegram. Creo, por ejemplo, un diccionario y necesito deducir la clave y el objeto de él, para formarlo como una cadena y colocarlo en un botón que pasará por el bucle for. Pero en lugar del resultado correcto, solo veo este error: TypeError: getattr(): el nombre del atributo debe ser una cadena.
Aquí está mi código:

def choose_language(update, conext):
    chat = update.effective_chat
    land = {
        'Eng':'en',
        'Rus':'ru'
    }
    b = []
    for k,v in land.items():
        a = k, v
        b.append(a)
    flatten = [str(item) for sub in b for item in sub]
    for key in flatten:
        button = [InlineKeyboardButton(f"{key}", callback_data='{key}')]

    # para key in land:
        # button = InlineKeyboardButton(str(land[key]).capitalize(), callback_data=str(key))
    reply_markup = InlineKeyboardMarkup(button)
    update.message.reply_text('Elige el idioma objetivo:', reply_markup=reply_markup)
Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema en el código radica en la creación de los botones utilizando la clase InlineKeyboardButton. El parámetro callback_data espera un argumento de tipo string, pero la variable key es una tupla en lugar de un string.

    Para solucionar esto, se debe modificar la comprensión de lista flatten para unir los pares clave-valor con un separador (por ejemplo, el guión bajo) en lugar de convertirlos a un string.

    Aquí está el código actualizado:

    def choose_language(update, context):
        chat = update.effective_chat
        land = {
            'Eng': 'en',
            'Rus': 'ru'
        }
        buttons = []
        for k, v in land.items():
            button_key = f'{k}_{v}'
            button = InlineKeyboardButton(k, callback_data=button_key)
            buttons.append([button])
    
        reply_markup = InlineKeyboardMarkup(buttons)
        update.message.reply_text('Choose target language:', reply_markup=reply_markup)
    

    En esta nueva versión, la variable button_key concatena los pares clave-valor con un separador de guión bajo. Luego, se llama a la clase InlineKeyboardButton con k (el nombre del lenguaje) como texto del botón, y button_key como datos de callback.

    Finalmente, la lista buttons se crea como una lista de listas, donde cada lista interna representa una fila de botones. Se llama a InlineKeyboardMarkup con buttons como argumento para crear el marcado de respuesta.

Comments are closed.