如果要繼續在已切換到使用屬性的對象上使用get_Field和set_Field(您只需訪問或分配給Field),則可以使用包裝器對象:
class NoPropertyAdaptor(object):
def __init__(self, obj):
self.obj = obj
def __getattr__(self, name):
if name.startswith("get_"):
return lambda: getattr(self.obj, name[4:])
elif name.startswith("set_"):
return lambda value: setattr(self.obj, name[4:], value)
else:
return getattr(self.obj, name)
如果您使用額外的語法(如對象的索引或迭代),或者您需要使用isinstance識別對象的類型,則會出現問題.
更復雜的解決方案是創建一個名稱重寫的子類,并強制對象使用它.這不完全是一個包裝,因為外部代碼仍將直接處理對象(因此魔術方法和isinstance)將按預期工作.這種方法適用于大多數對象,但對于具有花哨的元類魔法的類型以及某些內置類型可能會失敗:
def no_property_adaptor(obj):
class wrapper(obj.__class__):
def __getattr__(self, name):
if name.startswith("get_"):
return lambda: getattr(self, name[4:])
elif name.startswith("set_"):
return lambda value: setattr(self, name[4:], value)
else:
return super(wrapper, self).__getattr__(name)
obj.__class__ = wrapper
return obj