- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我用谷歌搜索了 calling __enter__ manually
但没有运气。所以让我们假设我有 MySQL 连接器类,它使用 __enter__
和 __exit__
函数(最初与 with
语句一起使用)连接/断开与数据库的连接。
让我们有一个使用其中 2 个连接的类(例如用于数据同步)。 注意:这不是我的真实场景,但它似乎是最简单的例子。
让它们一起工作的最简单方法是这样的类:
class DataSync(object):
def __init__(self):
self.master_connection = MySQLConnection(param_set_1)
self.slave_connection = MySQLConnection(param_set_2)
def __enter__(self):
self.master_connection.__enter__()
self.slave_connection.__enter__()
return self
def __exit__(self, exc_type, exc, traceback):
self.master_connection.__exit__(exc_type, exc, traceback)
self.slave_connection.__exit__(exc_type, exc, traceback)
# Some real operation functions
# Simple usage example
with DataSync() as sync:
records = sync.master_connection.fetch_records()
sync.slave_connection.push_records(records)
Q:这样手动调用__enter__
/__exit__
可以吗(有什么问题吗)?
Pylint 1.1.0 没有对此发出任何警告,我也没有找到任何关于它的文章(谷歌链接在开头)。
那么调用呢:
try:
# Db query
except MySQL.ServerDisconnectedException:
self.master_connection.__exit__(None, None, None)
self.master_connection.__enter__()
# Retry
这是一种好/坏的做法吗?为什么?
最佳答案
你的第一个例子不是一个好主意:
如果 slave_connection.__enter__
抛出异常会发生什么:
master_connection
获取其资源slave_connection
失败DataSync.__enter__
传播异常DataSync.__exit__
不运行master_connection
永远不会被清理!如果 master_connection.__exit__
抛出异常会怎样?
DataSync.__exit__
提前完成slave_connection
永远不会被清理!contextlib.ExitStack
可以在这里提供帮助:
def __enter__(self):
with ExitStack() as stack:
stack.enter_context(self.master_connection)
stack.enter_context(self.slave_connection)
self._stack = stack.pop_all()
return self
def __exit__(self, exc_type, exc, traceback):
self._stack.__exit__(self, exc_type, exc, traceback)
问同样的问题:
如果 slave_connection.__enter__
抛出异常会发生什么:
stack
清理 master_connection
如果 master_connection.__exit__
抛出异常会怎样?
slave_connection
会在调用之前清理干净好的,如果 slave_connection.__exit__
抛出异常会怎样?
ExitStack
确保调用 master_connection.__exit__
无论从属连接发生什么直接调用 __enter__
并没有什么问题,但是如果需要在多个对象上调用它,请确保正确清理!
关于python - 手动调用 __enter__ 和 __exit__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26635684/
在contextlib.py ,我看到 ExitStack 类正在通过类型对象 (type(cm)) 调用 __enter__() 方法,而不是直接调用给定对象 (cm) )。 我想知道为什么或为什么
def save_list(): f = open('data.txt', 'w') ii = 0 with itemMatrix[ii] as item: f.write(it
刚刚学习 with 语句 especially from this article 问题是,我可以将参数传递给 __enter__ 吗? 我有这样的代码: class clippy_runner:
我没有重新分配 open 关键字,但仍然收到此错误。有什么建议或指导可以解决我的错误吗? with tempfile.mkdtemp() as test_dir: print(tes
将上下文管理器定义为函数,很容易以编程方式从一个上下文管理器中输入一个单独的(或递归的)上下文管理器,如下所示: @contextmanager def enter(times): if ti
这个问题在这里已经有了答案: Object becomes None when using a context manager (3 个答案) 关闭 4 年前。 我在尝试运行代码时收到属性错误。
是否可以保证 __exit__() 方法在 __enter__() 有异常的情况下被调用? >>> class TstContx(object): ... def __enter__(self)
我最近想知道当 __enter__ 引发异常时不隐式调用 __exit__ 的原因是什么?为什么要这样设计?我正在实现服务运行器类以供 'with' 关键字使用,结果 __exit__ 从未被调用。
我是单元测试的新手,我正在尝试找到一种方法来测试 with 关键字是否在我的对象中正常工作。 在这种情况下,我的对象有一个创建临时目录的 __enter__ 方法和应该销毁它的 __exit__ 方法
我运行这个: import numpy as np import sys temp = np.array([[10, 20], [30, 40]]) with np.set_printoptions(
使用 with 语句,我们可以仅使用一层缩进/嵌套来输入许多上下文处理程序: >>> from contextlib import contextmanager >>> @contextmanager
我想在使用 __getattr__ 重定向调用的对象上使用 with。 但是,这似乎不适用于 __enter__ 方法 请考虑以下简化代码来重现错误: class EnterTest(object):
我用谷歌搜索了 calling __enter__ manually但没有运气。所以让我们假设我有 MySQL 连接器类,它使用 __enter__ 和 __exit__ 函数(最初与 with 语句
据我了解,上下文管理器的 __init__() 和 __enter__() 方法只被调用一次,一个接一个,没有任何机会其他要在两者之间执行的代码。将它们分成两种方法的目的是什么,我应该在每种方法中放入
关注 this related question ,虽然总是有一些库以独特的方式使用语言特性的例子,但我想知道是否返回 self 以外的值在 __enter__方法应该被认为是一种反模式。 这在我看来
有没有一种方法可以在上下文管理器的 __enter__ 方法中捕获异常,而无需将整个 with block 包装在 try 中? class TstContx(object): def __e
我问了this昨天的问题。但现在我意识到这是一个错误的问题。 __enter__ 函数通常包含 try block 吗? 最佳答案 如果您准备好从异常中正常恢复,他们可以,但是通常您会希望允许异常向上
问题几乎说明了一切。 我想以这种方式查看代码: >>>f = open("x.txt") >>>print contents of f.__enter__() #>> f = open("x.txt"
我有一个 python 包,我想在 Matlab 中使用它的类和方法。我知道这可以从 Matlab 2014b 开始直接完成。我的意思是您所要做的就是在语句的开头添加 py. 。然而,到目前为止一切顺
假设: class A(object): def __init__(self): self.cnt = 0 def __enter__(self): self.cnt += 1
我是一名优秀的程序员,十分优秀!