根据class个启动参数决定调用哪个class方法

Deciding which class method to be called according to class initiatiation parameters

我努力创建一个描述性标题,但我的挑战如下:

在我的 Python 应用程序中,我有一个通信模块,它以前只使用一种传输类型,串行。现在我还希望它包含另一个传输层,称为 RTT。 我的 class COM 包含 connectsendreadlog 等方法。现在我需要所有这些方法的两个不同版本,我想要它,以便在 class 实例化时决定调用哪些方法。

例如 comlink = COM('RTT') 将使用特定于 RTT 协议的发送、读取、连接集,反之亦然,无需创建额外的 class 并决定哪个 class 在更高层次上使用。

这可能吗?

COM() 成为 returns 正确 class 实例的函数。 例如

def COM(ctype):
    try:
        klass = {
            'RTT' : ComRTT,
            'serial' : ComSerial}[ctype]
    except KeyError:
        raise ValueError("Invalid connection class: {}".format(ctype))
    instance = klass()
    return instance

>>> com = COM('RTT')

您也可以将此作为 class 基数 class 的方法。

class Communication:
    @classmethod
    def from_type(cls, ctype):
        try:
            klass = {
                'RTT' : ComRTT,
                'serial' : ComSerial}[ctype]
        except KeyError:
            raise ValueError("Invalid connection class: {}".format(ctype))
    return klass()

>>> com = Communication.from_type('RTT')

结果和模式相同,但后者可能更可取,因为它(可以说)更清楚地表明它与 Communication class(es) 有关。

鉴于我完全支持@Hannes Ovrén 的评论和回答,这是另一种方法

class A():
    def __init__(self, protocol='SERIAL'):
        std_f = ('connect', 'send', 'read', 'log')
        protocols = ('RTT', 'SERIAL')
        if protocol not in protocols:
            print("Protocol not supported!")
            raise Exception # your exception here

        prot_f = [getattr(self, name+'_'+protocol.lower()) for name in std_f]
        for f, new_f in zip(std_f, prot_f):
            setattr(self, f, new_f)

    def connect_serial(self, hostname):
        print('I am serial connect', hostname)
    def send_serial(self, hostname):
        print('I am serial send', hostname)
    def read_serial(self, hostname):
        print('I am serial read', hostname)
    def log_serial(self, hostname):
        print('I am serial log', hostname)

    def connect_rtt(self, hostname):
        print('I am RTT connect', hostname)
    def send_rtt(self, hostname):
        print('I am RTT send', hostname)
    def read_rtt(self, hostname):
        print('I am RTT read', hostname)
    def log_rtt(self, hostname):
        print('I am RTT log', hostname)

基本上,它根据给定的协议

在实例化class时分配标准函数的名称
>>> from two_types_of_methods import A
>>> a=A('RTT')
>>> a.connect('myserv.com')
I am RTT connect myserv.com
>>> a.send('myserv.com')
I am RTT send myserv.com
>>> a.read('myserv.com')
I am RTT read myserv.com
>>> a.log('myserv.com')
I am RTT log myserv.com
>>> b=A()
>>> b.connect('myserv.com')
I am serial connect myserv.com
>>> b.send('myserv.com')
I am serial send myserv.com
>>> b.read('myserv.com')
I am serial read myserv.com
>>> b.log('myserv.com')
I am serial log myserv.com