Python 使用动态继承类指定对象的特征
我有一个对象,它封装了一个具有某些特征的网络配置文件。例如,我的配置文件有一个连接,根据连接的不同,它可能有或不可能有IP选项static或dhcp 因此,我的第一次尝试是使用一个从dict扩展而来的普通类,并添加一些辅助函数:Python 使用动态继承类指定对象的特征,python,oop,multiple-inheritance,Python,Oop,Multiple Inheritance,我有一个对象,它封装了一个具有某些特征的网络配置文件。例如,我的配置文件有一个连接,根据连接的不同,它可能有或不可能有IP选项static或dhcp 因此,我的第一次尝试是使用一个从dict扩展而来的普通类,并添加一些辅助函数: class Profile(dict): IP_CONNECTIONS = ('ethernet', 'wireless', 'pppoe') def is_ethernet(self): return self['Connection'] == 'et
class Profile(dict):
IP_CONNECTIONS = ('ethernet', 'wireless', 'pppoe')
def is_ethernet(self): return self['Connection'] == 'ethernet'
def is_wireless(self): return self['Connection'] == 'wireless'
def is_wireless_adhoc(self): return self.is_wireless() and 'AdHoc' in self
def has_ip(self)
return self['Connection'] in self.IP_CONNECTIONS
def has_ip_static(self)
if not self.has_ip():
return False
if self.is_ipv4():
return self['IP'] == 'static'
if self.is_ipv6():
return self['IP6'] == 'static'
return False
def has_ip_dhcp(self):
if not self.has_ip():
return False
if self.is_ipv4():
return self['IP'] == 'dhcp'
if self.is_ipv6():
return self['IP6'] == 'dhcp' or self['IP6'] == 'dhcp-noaddr'
return False
def is_ipv4(self): return self.has_ip() and 'IP' in self
def is_ipv6(self): return self.has_ip() and 'IP6' in self
def get_client(self):
if self.has_ip_dhcp() and 'DHCPClient' in self:
return self['DHCPClient']
return None
这是可行的,但我有一个庞大的类,包含大量的is,并且具有特征函数。其中大多数只用于非常特定的配置文件,大多数情况下返回False
然后我想到我可以用继承来描述特征
尝试后,未能实现元类,因为调用_new___方法时数据尚不可用。我想出了这样的办法:
def load_profile(filename):
data = _read_profile(filename)
bases = _classify_profile(data)
baseclass = type('Profile', bases, {})
return baseclass(data)
class IP:
CONNECTIONS = ('ethernet', 'wireless')
class IPv4(IP):
def is_static(self):
return self['IP'] == 'static'
class IPv6(IP):
def is_static(self):
return self['IP6'] == 'static'
class DHCP:
def get_client(self):
return self['DHCPClient'] if 'DHCPClient' in self else None
class Wireless:
def is_adhoc(self):
return 'AdHoc' in self
def _classify_profile(data):
classes = [dict]
if data['Connection'] == 'wireless':
classes.append(Wireless)
if data['Connection'] in IP.CONNECTIONS:
if 'IP' in data:
classes.append(IPv4)
if data['IP'] == 'dhcp':
classes.append(DHCP)
if 'IP6' in data:
classes.append(IPv6)
if data['IP6'] == 'dhcp' or data['IP6'] == 'dhcp-noaddr':
classes.append(DHCP)
return tuple(classes)
以前我做profile.has_ip的时候,现在我只是用isinstanceprofile,ip来测试它。在我看来,这一点在责任划分良好的情况下更为明确
问:这是实现动态继承的好方法吗?什么是蟒蛇式的方法
提前谢谢 我真的不知道动态继承是什么意思,但我会这样写:
base_classes = []
class IP(dict):
CONNECTIONS = ('ethernet', 'wireless')
def is_static(self):
raise NotImplementedError('To be implemented in subclasses.')
@classmethod
def wants_the_meaningful_named_data(cls, data):
return False
base_classes.append(IP)
class IPv4(IP):
def is_static(self):
return self['IP'] == 'static'
@classmethod
def wants_the_meaningful_named_data(cls, data):
return data['Connection'] in cls.CONNECTIONS and 'IP' in data
base_classes.append(IPv4)
class IPv6(IP):
def is_static(self):
return self['IP6'] == 'static'
@classmethod
def wants_the_meaningful_named_data(cls, data):
return data['Connection'] in cls.CONNECTIONS and 'IP6' in data
base_classes.append(IPv6)
def load_profile(filename):
data = _read_profile(filename)
for base_class in base_classes:
if base_class.wants_the_meaningful_named_data(data):
return base_class(data)
return dict(data)
我喜欢这样的东西。我不认为有必要研究元类 我非常喜欢这个关于设计的视频:@User非常有趣。谢谢IP类只是一个例子。概要文件具有更多需要同时实现的特性。每个“连接”值都有一个大类,所以我可以做isinstanceprofile、Wireless和profile.is_adhoc。另一个例子是,如果“IP”是“dhcp”或“IP6”是“dhcp”或“dhcp noaddr”,我将从具有profile.get_client.You的dhcp类扩展。我想要profile.is_wireless和profile.is_adhoc更好。