根据class个启动参数决定调用哪个class方法
Deciding which class method to be called according to class initiatiation parameters
我努力创建一个描述性标题,但我的挑战如下:
在我的 Python 应用程序中,我有一个通信模块,它以前只使用一种传输类型,串行。现在我还希望它包含另一个传输层,称为 RTT。
我的 class COM
包含 connect
、send
、read
、log
等方法。现在我需要所有这些方法的两个不同版本,我想要它,以便在 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
我努力创建一个描述性标题,但我的挑战如下:
在我的 Python 应用程序中,我有一个通信模块,它以前只使用一种传输类型,串行。现在我还希望它包含另一个传输层,称为 RTT。
我的 class COM
包含 connect
、send
、read
、log
等方法。现在我需要所有这些方法的两个不同版本,我想要它,以便在 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