Как перегрузить одноименные методы разных интерфейсов аннотациями типов в Python 3 - PullRequest
2 голосов
/ 12 июля 2020

Итак, у меня есть код Python 3 вроде этого:

from abc import ABC, abstractmethod                                                                                                                                                                                                                                                         
from datetime import datetime                                                                                                                                                                                                                                                               
                                                                                                                                                                                                                                                                                            
class IfaceA(ABC):                                                                                                                                                                                                                                                                          
    @abstractmethod                                                                                                                                                                                                                                                                         
    def pass_data(self, data: str):                                                                                                                                                                                                                                                         
        pass                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                            
class IfaceB(ABC):                                                                                                                                                                                                                                                                          
    @abstractmethod                                                                                                                                                                                                                                                                         
    def pass_data(self, data: datetime):                                                                                                                                                                                                                                                    
        pass                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                            
class MyClass(IfaceA, IfaceB):                                                                                                                                                                                                                                                              
    def pass_data(self, data: str):                                                                                                                                                                                                                                                         
        print("str", data)                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                            
    def pass_data(self, data: datetime):                                                                                                                                                                                                                                                    
        print("datetime", data)                                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                                                                            
def main():                                                                                                                                                                                                                                                                                 
    c = MyClass()                                                                                                                                                                                                                                                                           
    c.pass_data("Any string.")                                                                                                                                                                                                                                                              
    c.pass_data(datetime.now())                                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                                                                            
if __name__ == "__main__":                                                                                                                                                                                                                                                                  
    main()

, и он дает мне такой вывод:

datetime Any string.
datetime 2020-07-13 02:00:34.676715

The IfaceA.pass_data метод с аргументом str не использовался.

Есть ли способ заставить это работать как в C ++?

Ответы [ 2 ]

0 голосов
/ 12 июля 2020

Я не думаю, что это можно сделать без каких-то уродливых c хаков, отличных от pythoni. Лучшее, что вы можете сделать без хаков или сторонних библиотек (с хаками), - это.

from datetime import datetime
from functools import singledispatchmethod


class MyClass:
    @singledispatchmethod
    def pass_data(self, val):
        raise NotImplementedError

    @pass_data.register
    def prints_str(self, data: str):
        print("str", data)


    @pass_data.register
    def prints_datetime(self, data: datetime):
        print("datetime", data)


def main():
    c = MyClass()
    c.pass_data("Any string.")
    c.pass_data(datetime.now())


if __name__ == "__main__":
    main()
0 голосов
/ 12 июля 2020

вы можете использовать мультиметод

 from abc import ABC, abstractmethod                                                                                                                                                                                                                                                         
from datetime import datetime                                                                                                                                                                                                                                                               
from multimethod import multimethod
                                                                                                                                                                                                                                                                                          
class IfaceA(ABC):                                                                                                                                                                                                                                                                          
    @abstractmethod                                                                                                                                                                                                                                                                         
    def pass_data(self, data: str):                                                                                                                                                                                                                                                         
        pass                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                            
class IfaceB(ABC):                                                                                                                                                                                                                                                                          
    @abstractmethod                                                                                                                                                                                                                                                                         
    def pass_data(self, data: datetime):                                                                                                                                                                                                                                                    
        pass                                                                                                                                                                                                                                                                                
                                                                                                                                                                                                                                                                                            
class MyClass(IfaceA, IfaceB):
    @multimethod                                                                                                                                                                                                                                                           
    def pass_data(self, data: str):                                                                                                                                                                                                                                                         
        print("str", data)
    @multimethod                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
    def pass_data(self, data: datetime):                                                                                                                                                                                                                                                    
        print("datetime", data)                                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                                                                            
def main():                                                                                                                                                                                                                                                                                 
    c = MyClass()                                                                                                                                                                                                                                                                           
    c.pass_data("Any string.")                                                                                                                                                                                                                                                              
    c.pass_data(datetime.now())                                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                                                                            
if __name__ == "__main__":                                                                                                                                                                                                                                                                  
    main()
...