python - 在 with block 中重新分配变量

标签 python

是否可以在退出 block 之前重新分配 with block 的对象?

具体用例

我与 FTP 服务器交互,偶尔会在传输过程中断开连接,而 IT 部门不愿意对此采取任何措施。作为我自己工具的解决方法,我使用了一个包装器,它会在放弃之前重试传输几次:

def retry(conn, max_tries=3, **kwargs):
    this_try = 1
    while (this_try <= max_tries):
        try:
            # upload / download / whatever
            return conn
        except ftplib.all_errors:
            conn.quit()
            time.sleep(60)
            conn = ftplib.FTP(**kwargs)
            this_try += 1

这个包装器工作正常,但似乎不能在 with block 中使用,就像可以使用普通的 FTP 连接一样。如果 except 子句被命中,连接将重新建立,但是在退出 with block 时,python 将尝试关闭原始的 conn,不是新的:

with ftplib.FTP(**kwargs) as conn:
    conn = retry(conn, **kwargs)

这可以用自定义上下文管理器来演示,显示 python 从原始对象调用 __exit__(),即使变量在 block 中重新分配也是如此:

>>> class Echo(object):
...     def __enter__(self):
...             print('entering ' + repr(self))
...             return self
...     def __exit__(self, *args):
...             print('exiting ' + repr(self))
...
>>> with Echo() as e:
...     e = Echo()
...
entering <__main__.Echo object at 0x026C14F0>
exiting <__main__.Echo object at 0x026C14F0>
>>> e
<__main__.Echo object at 0x026C1410>

如何在 with block 中重新分配 conn 以便 python 在最新的对象上调用 __exit__() 方法,而不是原来的?这样的事情甚至是可能的,还是我被迫没有 with block 并且必须记住在任何地方调用 conn.quit()

如果重要的话,我想要一些与 python 2 和 3 都兼容的东西。如果一个解决方案与两者都不兼容,那么我更喜欢 python 3 特定的解决方案而不是 python 2 特定的解决方案

最佳答案

回答您的一般性问题,不,您不能,如 PEP 343 所示“规范:with 语句”。您上下文中的变量 e 被保存到一个内部变量中,该变量在拆卸时使用。 对于具体的FTP连接,其他答案中已经提出了一些其他选项。

关于python - 在 with block 中重新分配变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36558280/

相关文章:

python - 如何根据 Django 中的字段向某些用户添加特定权限 View ?

python - 在列表中移动项目?

python - 在 pandas DataFrame 上使用 Python 中的 R lm 函数

python - 如何获得图像凸出效果?

python - list() 给出类型错误 : 'Node' object is not callable - BUT ONLY AFTER SOME CODES

python - 在 python 中使用 bitly_api 的短 URL

python selenium xpath 解决方案

python - 如何解决 TypeError : can only concatenate str (not "int") to str

python - 将 2 1/2 小时添加到 python 中的时间对象

Python将整数四舍五入到下一百