我有一個封裝具有某些特徵的網絡配置文件的對象。例如,我的檔案有連接並根據它,它可以或不可以有IP選項(靜態或DHCP)。使用動態繼承類來指定對象的特徵
所以,我的第一次嘗試使用從字典延伸的正常類,並添加了一些輔助功能:
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_*
和has_*
特徵功能。他們中的大多數只會用於非常具體的配置文件,並且大多數時候會返回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()
之前,現在我只是isinstance(profile, IP)
測試。這在我看來更加明確,責任分工很好。
問題:這是實現動態繼承的好方法嗎?這樣做的pythonic方式是什麼?
提前致謝!
我很喜歡這個關於設計的視頻:http://vimeo.com/26330100 – User
@User很有意思。謝謝! – guide42