C ++ чисто виртуальные функции и этот указатель в Python - PullRequest
0 голосов
/ 16 мая 2018

Я бывший программист на С ++ и несколько месяцев погружался в python, и это было здорово.Я занимаюсь портированием кода и столкнулся с проблемой, в которой я не уверен, что это лучший путь.Есть много способов снять шкуру с кошки, но я ищу совет о том, что было бы «лучшим» и / или наиболее питоническим способом сделать что-то похожее на приведенный ниже раздел кода на c ++.

I 'Мы вырезали код до тривиального «репродуктора», чтобы подчеркнуть происходящее.По существу, существует четко определенный интерфейс обратных вызовов, которые сервер будет вызывать при возникновении определенных событий.Когда сервер создается, ему предоставляется интерфейс обратного вызова в качестве аргумента.

В приведенном ниже случае клиент реализовал эти обратные вызовы на себе, и, таким образом, при создании сервера он предоставляет * thisуказатель.

Это что-то похожее в Python?Любые предложения будут высоко оценены.

#include <iostream>

// Client Feed Handler function Interface
class ClientFeedHandlersI
{
public:
    virtual void HandlerFeed1() = 0;
    virtual void HandlerFeed2() = 0;
};

// A very basic server
class Server
{
public:
    Server(ClientFeedHandlersI& handlers) 
        : mHandlers(handlers) {}

void Start()
{
    // Create some random events to illustrate
    for (int i = 0; i < 10; ++i)
        EventLoopHandler();
}
private:
    void EventLoopHandler()
    {
        if (rand() % 10 > 5)
            mHandlers.HandlerFeed1();
        else
            mHandlers.HandlerFeed2();
    }

    ClientFeedHandlersI& mHandlers;
};

// A really simple client
class Client : private ClientFeedHandlersI
{
public:
    Client() 
      : mMyServer(*this)
    {
        mMyServer.Start();
    }

private:
    void HandlerFeed1() override { std::cout << "HandlerFeed1 called\n"; }
    void HandlerFeed2() override { std::cout << "HandlerFeed2 called\n"; }

    Server mMyServer;
};

int main()
{
    auto c = Client();
}

Итак, вот попытка портирования на python.Обратите внимание, что в примере с реальным миром существует более 20 функций-обработчиков клиентских фидов, поэтому я хочу принудительно настроить интерфейс с помощью @ abstractmethod.

# python 3.6
from abc import ABC, abstractmethod

class ClientFeedHandlersI(ABC):

    def __init__(self):
        pass

    @abstractmethod
    def handler_feed_1(self):
        pass

   @abstractmethod
   def handler_feed_2(self):
        pass

class Server:

    def __init__(self, clientCallBacks:ClientFeedHandlersI):

        self.clientCallBacks = clientCallBacks

    def start(self):
        for ii in range(10):
            self.event_loop_handler()

    def event_loop_handler(self):
        import random
        if random.randint(0,10) > 5:
            self.clientCallBacks.handler_feed_1()
        else:
            self.clientCallBacks.handler_feed_2()


class Client(ClientFeedHandlersI):

    def __init__(self):

        self.server = Server(self)
        self.server.start()

    def handler_feed_1(self):
        print("HandlerFeed1 called\n")
    def handler_feed_2(self):
        print("HandlerFeed2 called\n")

if __name__ == '__main__':
    c = Client()

Редактировать: приведенный выше пример кода теперь работает в соответствии скод c ++.

1 Ответ

0 голосов
/ 16 мая 2018

Пример кода Python ниже C ++ в OP теперь работает.

...