有没有更好的方法来组织Python(3.6.2)文件?

问题描述 投票:0回答:2

抽象。

我有两个python文件。第一个读取一些输入(文本),第二个读取一些函数。这里的问题是我用来寻找我需要的功能的方法。现在我使用If / Elif方法来比较输入和函数,但是这个方法需要比较存储在第二个文件中的所有函数和输入,我在想“这是最好的方法吗?” 。

完整的解释。

我正在尝试构建一个Telegram聊天机器人,只是为了练习一些Python。在我做任何事情之前,我画了一张心理地图,知道我希望这个脚本会做什么。由于这个心理地图,我想到了将代码分割到不同文件中的想法,以便更好地组织所有内容并使调试过程更容易一些。所以,我做到了。我将凭证(用于api)存储在一个文件中,将主机存储在其他文件中,将函数存储在其他文件中。我用From Credentials import *From Comands import *将文件导入大型机。当任何文本进入机器人时,它首先检查它是如何开始的,如果它以“/”开头,那么它将存储在变量中的斜杠之后的任何内容并将其作为参数发送到函数文件。什么时候它开始寻找所需的确切命令并执行它。它有效,但我猜测是否有更好的方法来做到这一点。我希望我能很好地解释这个问题,你可以帮助我。这是我正在谈论的代码摘录。

mainframe.py

from Comands import *
from credentials import *

...

if text.startswith("/"):
            comando = text[1:]
            print(comando)
            Comands.search(comando)
elif text in items:
            db.delete_item(text, chat)
            items = db.get_items(chat)
            keyboard = build_keyboard(items)
            send_message("Select an item to delete", chat, keyboard)
else:
            db.add_item(text, chat)
            items = db.get_items(chat)
            message = "\n".join(items)
            send_message(message, chat)
...

Comands.py

from message_dictionary import *
from mainframe import *

def search(comando):
    if comando == "start":
        def start():
            keyboard = build_keyboard(acuerdo)
            send_message(mensaje["start"], chat, keyboard)
    elif comando == "done":
        def done():
            keyboard = build_kerboard(items)
            send_message("Select an item to delete", chat, keyboard)

python
2个回答
0
投票

首先,我将从2条建议开始:

  • 不要在导入中使用星号(以后很难分辨函数的位置)
  • 尽量避免循环导入(在mainframe.py中导入命令并在command.py中导入主机)

mainframe.朋友

import command

comando_str = 'str_command'

# at this stage we want to call command.str_command(), but we have a string, not a function
if hasattr(command, comando_str):  # let's check if such command exist in `command` module
    comando_function = getattr(command, comando_str)  # now let's get a reference to that function

    # we can now call comando_function()!
    # but maybe you have some parameters to call (like passing in `keyboard`)
    arg_count = comando_function.__code__.co_argcount  # total number of arguments to the function
    # co_varnames has all the variables that function would use, but arguments come firs
    arg_names = comando_function.__code__.co_varnames[:arg_count]  

    if arg_count >= 1 and arg_names[0] == 'keyboard':
         comando_function(keyboard)
    elif arg_count == 0:  # function require no arguments
         comando_function()
    else:
        raise Exception('Function %s could not be called', comando_str)
else:
    raise Exception('Function command.%s is not declared', comando_str)

command.朋友

import message_dictionary as md  # no *!

def str_command(keyboard):
    md.send_message(mensaje["start"], chat, keyboard)  # now I know that send_message is in md (message_dictionary)

def start():
    keyboard = build_keyboard(acuerdo)  
    send_message(mensaje["start"], chat, keyboard)  

关于你的comand.py的一些注意事项:

def search(comando):  # ok
    if comando == "start":  # ok
        # here you define function `start`
        # yet, you have not called `start` function 
        # so, when you exit `search` function, this function is gone!
        def start():
            keyboard = build_keyboard(acuerdo)  # where is acuerdo is declared?
            send_message(mensaje["start"], chat, keyboard)  # where mensaje and chat are declared?
    elif comando == "done":
        # same problem as with `start` function above
        def done():
            keyboard = build_kerboard(items)
            send_message("Select an item to delete", chat, keyboard)

修改了comand.py以返回可调用函数(以解决注释中的问题):

def search(comando): 
    if comando == "start":
        def start(): 
            keyboard = build_keyboard(acuerdo)  
            send_message(mensaje["start"], chat, keyboard)  
        return start
    elif comando == "done":
        # same problem as with `start` function above
        def done():
            keyboard = build_kerboard(items)
            send_message("Select an item to delete", chat, keyboard)
        return done

修改了片段mainframe.py以使用返回值:

if text.startswith("/"):
    comando = text[1:]
    print(comando)  # look at the logging as a fancy replacing for print
    call_me = Comands.search(comando)
    if call_me:  # checking that something is returned (not None)
        call_me()  # example of calling it

0
投票

这里是。

mainframe.py(实际上称为Prubeas.py)

#PYTHON 3.6.2
#LGsus

import json
import requests
import time
import urllib
from dbhelper import DBHelper
from credentials import *
from message_dictionary import *
import Comands

db = DBHelper()

#DECLARAR ID DEL BOT Y URL DE TELEGRAM
URL = "https://api.telegram.org/bot{}/".format(telegram_token)

#CONSULTAR ESTADO
def get_url(url):
    response = requests.get(url)
    content = response.content.decode("utf8")
    return content

#CAMBIAR DE JSON A PYTHON (PARSE)
def get_json_from_url(url):
    content = get_url(url)
    js = json.loads(content)
    return js

#SOLICITAR LISTA DE MENSAJES
def get_updates(offset=None):
    url = URL + "getUpdates?timeout=100"
    if offset:
        url += "&offset={}".format(offset)
    js = get_json_from_url(url)
    return js

#DETERMINAR MENSAJES NO  LEÍDOS
def get_last_update_id(updates):
    update_ids = []
    for update in updates["result"]:
        update_ids.append(int(update["update_id"]))
    return max(update_ids)

#RESPONDER A TODOS LOS NO LEIDOS
def handle_updates(updates):
    for update in updates["result"]:
        text = update["message"]["text"]
        chat = update["message"]["chat"]["id"]
        items = db.get_items(chat)
        if text.startswith("/"):
            comando = text[1:]
            print(comando)
            Comands.search(comando)
            #fin = text.find(" ")
            #print(fin)

            #if text == "/done":
            #    keyboard = build_keyboard(items)
            #    send_message("select an item to delete", chat, keyboard)
            #elif text == "/start":
            #    keyboard = build_keyboard(acuerdo)
            #    send_message(mensajes["start"], chat, keyboard)
            #elif text.startswith("/"):
            #    continue
        elif text in items:
            db.delete_item(text, chat)
            items = db.get_items(chat)
            keyboard = build_keyboard(items)
            send_message("Select an item to delete", chat, keyboard)
        else:
            db.add_item(text, chat)
            items = db.get_items(chat)
            message = "\n".join(items)
            send_message(message, chat)

#SOLICITAR ULTIMO MENSAJE Y ID DEL CHAT
def get_last_chat_id_and_text(updates):
    global Texto
    global full_last
    num_updates = len(updates["result"])
    lista = updates["result"]
    data = json.dumps(lista)
    last_update = num_updates - 1
    full_last = updates["result"][last_update]
    Texto = "text" in full_last["message"]
    if Texto == True:
        text = updates["result"][last_update]["message"]["text"]
    else:
        text = "Entrada invalida"
    chat_id = updates["result"][last_update]["message"]["chat"]["id"]
    return (text, chat_id)

#CREAR EL TECLADO
def build_keyboard(items):
    keyboard = [[item] for item in items]
    reply_markup = {"keyboard":keyboard, "one_time_keyboard":True}
    return json.dumps(reply_markup)

#ENVIAR MENSAJE
def send_message(text, chat_id, reply_markup=None):
    text = text.encode(encoding='utf-8')
    text = urllib.parse.quote_plus(text)
    url = URL + "sendMessage?text={}&chat_id={}&parse_mode=Markdown".format(text, chat_id)
    if reply_markup:
        url += "&reply_markup={}".format(reply_markup)
    get_url(url)
    print (text)

text, chat = get_last_chat_id_and_text(get_updates())
send_message(text, chat)

##EJECUTAR
def main():
    db.setup()
    last_update_id = None
    while True:
        updates = get_updates(last_update_id)
        if len(updates["result"]) > 0:
            last_update_id = get_last_update_id(updates) + 1
            handle_updates(updates)
        time.sleep(0.5)

#CONDICION PARA EJECUTAR
if __name__ == '__main__':
    main()





#import ccxt

#b = ccxt.bitso({
#    'apiKey': "XXXXXX",
#    'secret': "XXXXXX",
#    'verbose': False,
#    })
#
#print(b.fetchBalance())

它在这段代码结尾处评论的是一个API,我将在稍后尝试使用,一旦我完成了电报api。

coma NDS.朋友

#Lista de comandos

from message_dictionary import *
from Prubebas import *

def search(comando):
    if comando == "start":

    #def start():
        keyboard = build_keyboard(acuerdo)
        send_message(mensaje["start"], chat, keyboard)

    def done():
        keyboard = build_kerboard(items)
        send_message("Select an item to delete", chat, keyboard)

我为混合语言道歉。非常感谢你的帮助,谢谢。

© www.soinside.com 2019 - 2024. All rights reserved.