使用" self"从静态方法调用非静态方法

时间:2017-05-23 03:23:24

标签: python python-3.x

我是Python的初学者,所以请...好吗?

无论如何,我需要使用静态方法来调用另一个方法,这需要使用" self" (因此,我认为这是一种常规方法)。我正在使用Telethon,一个Telegram的Python实现。我已经尝试了其他问题,但我似乎无法找到解决问题的方法。

该计划的概述(如果我错了,请纠正我):

1)interactive_telegram_client是telegram_client的子类,它创建一个实例。

#interactive_telegram_client.py
class InteractiveTelegramClient(TelegramClient):
    super().__init__(session_user_id, api_id, api_hash, proxy)

2)当InteractiveTelegramClient运行时,它会添加一个update_handler self.add_update_handler(self.update_handler)来不断检查收到/发送的消息,并将其打印到屏幕

#telegram_client.py
def add_update_handler(self, handler):
    """Adds an update handler (a function which takes a TLObject,
      an update, as its parameter) and listens for updates"""
    if not self.sender:
        raise RuntimeError(
            "You should connect at least once to add update handlers.")

    self.sender.add_update_handler(handler)

#interactive_telegram_client.py
@staticmethod
def update_handler(update_object):
    try:
        if type(update_object) is UpdateShortMessage:
            if update_object.out:
                print('You sent {} to user #{}'.format(update_object.message,
                                                       update_object.user_id))
            else:
                print('[User #{} sent {}]'.format(update_object.user_id,
                                                  update_object.message))

现在,我的目标是在收到消息后发回自动回复消息。因此,我认为InteractiveTelegramClient.send_ack(update_object)方法中添加对方法update_handler的调用将满足我的需求。

#interactive_telegram_client.py
def send_ack(self, update_object):
    entity = update_object.user_id
    message = update_object.message
    msg, entities = parse_message_entities(message)
    msg_id = utils.generate_random_long()

    self.invoke(SendMessageRequest(peer=get_input_peer(entity),
        message=msg,random_id=msg_id,entities=entities,no_webpage=False))

但是,正如您所看到的,我要求self调用此函数(基于readme,我假设client引用与{{1}相同的内容}})。由于方法self是静态的,update_handler不会被传递,因此我不能这样调用这个调用。

我可能失败的策略包括:

1)为自动回复实例化一个新客户端 - 为每个回复创建一个新的客户端/对话......

2)使所有方法都是非静态的 - 由于其他方法也被修改,因此涉及大量工作

3)观察者模式(听起来像个好主意,我试过,但由于缺乏技能,没有成功)

我想知道是否还有其他方法可以解决这个问题?或者它可能很容易,只是我在某处有一些误解?

忘记提及由于我的项目有一些限制,我只能使用Telethon,而不是寻找其他选择。允许采用另一个库(比如现有的自动回复库),虽然我没有真正研究过,因为合并它和Telethon可能对我来说太难了......

1 个答案:

答案 0 :(得分:1)

  

基于自述文件,我假设客户端引用与self相同的东西

正确,因为InteractiveTelegramClientTelegramClient的子类,因此,self是扩展客户端的实例。

  

为自动回复实例化新客户端 - 为每个回复创建新客户端/对话

这将要求您创建另一个授权向登录发送另一个代码请求,因为您无法同时使用相同的*.session

  

使所有方法都是非静态的 - 由于其他方法也被修改,所以涉及大量的工作

它不需要这么多的工作。请考虑以下示例:

class Example:
    def __init__(self, a):
        self.a = a

    def do_something(self):
        Example.other_method()

    @staticmethod
    def other_method():
        print('hello, world!')

相当于:

class Example:
    def __init__(self, a):
        self.a = a

    def do_something(self):
        self.other_method()

    @staticmethod
    def other_method():
        print('hello, world!')

使用self.或类名来引用类中的静态方法并不重要。由于InteractiveClientExample已使用self.,因此您只需要更改:

@staticmethod
def update_handler(update_object):

def update_handler(self, update_object):

有关@staticmethod装饰器的更多信息,您可以refer to the docs