with BaseObject.ethernet_device(ip_addr) as obj:如果函式中有錯誤,我一直在嘗試找到一種完全退出/跳過我的代碼塊的__enter__方法。
在下面的示例中,這將是如果設備不存在于網路上。任何解決方案都有望取代這條線return None(我知道這不是所需要的)。
class BaseObject(object):
@class_method
def ethernet_device(cls, host:str):
return EthernetDevice(host)
def __enter__(self):
return self
def __exit__(self, *args):
self._inst.close()
class EthernetDevice(BaseObject):
def __init__(self, host: str):
self._host = host
def __enter__(self):
try:
socket.inet_ntoa(self._host)
ip_addr = self._host
except:
logger.debug(f'{self._host} is not a valid IP address: trying as a hostname')
try:
logger.debug(f"Trying to resolve host {self._host}")
ip_addr = socket.gethostbyname(self._host)
except socket.gaierror:
logger.error(f"Couldn't resolve host {self._host}")
return None
self._inst = vxi11.Instrument(ip_addr)
return super().__enter__()
用法:
with BaseObject.ethernet_device(ip_addr) as device:
print(device.id)
uj5u.com熱心網友回復:
這里唯一的答案是在內部引發例外__enter__;__exit__如果無例外退出,將始終運行__enter__(假設您沒有設法對解釋器進行段錯誤或呼叫os._exit故意殺死程式而不運行清理塊)。
這將把它放在呼叫者身上以捕獲例外(with用try/包裝except)以防止它冒泡通程序式的其余部分。
如果呼叫者不喜歡為此縮進整個塊,他們可以使用 縮小范圍,ExitStack但這是唯一可用的“改進”,它仍然需要__enter__引發例外:
with contextlib.ExitStack() as stack:
try:
device = stack.enter_context(BaseObject.ethernet_device(ip_addr)
except CustomException:
return # Or do something else to skip remaining code
# Rest of code using device
# device is cleaned up for you if it exists
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/446019.html
