【问题标题】:Overriding a built-in class method that another class I want to inherit from relies on覆盖我要继承的另一个类所依赖的内置类方法
【发布时间】:2021-12-09 03:59:02
【问题描述】:

所以我正在编写一个使用 python 多处理 BaseManager 类的脚本/应用程序。现在在大多数情况下它工作得很好,我唯一的问题是我使用serve_forever 作为阻塞语句然后继续前进但是当我想终止或退出serve_forever() 功能(性)它自动退出并终止应用程序,但就像我提到的,在完全退出之前我还有一些事情需要处理。

我可以通过使用stop_event.set() 设置停止事件来退出serve_forever()。现在这一切都很好而且很花哨,但是根据来源 (https://github.com/python/cpython/blob/3.6/Lib/multiprocessing/managers.py#L147) serve_forever 明确声明 sys.exit(0) 并且是 BaseManager 在其定义中使用的 Server 类的一部分。本质上我想删除那条线(sys.exit(0))。我将如何实现这一点?

当我搜索时,我会得到诸如猴子补丁之类的结果?我可以只子类化 Server 类,明确定义 serve_forever 为完全相同的代码,但没有 sys.exit(0) 行,就这样结束了吗?有些东西告诉我那是行不通的。我要继承 Server 和 BaseManager 吗?

谢谢!

【问题讨论】:

  • 首先,Python 中有一个错误,我会修复它。其次,为什么要使用serve_forever 方法而不是start()?我可以为您提供猴子修补解决方案、继承解决方案以及所有其他类型的东西,这些都是矫枉过正的,可能会导致比解决的问题更多的问题。
  • 好吧,我想这只是一个非常方便的解决方案,但从我收集到的你建议重新实现 serve_forever 作为我自己的启动方法是要走的路吗?
  • 毫无疑问。
  • 添加了官方答案,如果它满足您的需求,您将能够接受并关闭问题。
  • 感谢您的帮助,我真的很讨厌一直问,但我尝试搜索但找不到太多,我实际上并没有使用这个库的多处理功能更多进程之间的通信功能所以我实际上是在自己的线程中运行serve_forever,然后调用join()来阻止主逻辑,但允许其他线程运行,直到我决定继续,那么完成创建新启动函数的最佳方法是什么?子类化并覆盖 Server 类的 start 方法?但是我如何告诉 BaseManager 使用子类 Server 类

标签: python-3.x overriding subclassing


【解决方案1】:

尝试猴子补丁或继承内部类将导致代码在 Python 版本之间不兼容,甚至补丁也不兼容。

除此之外,这些解决方案将变得不必要的复杂和复杂,并且总体上不受欢迎。

我强烈建议通过将start() 方法与事件一起使用来重新实现serve_forever()。等待事件被调用,或者,如果不可能,循环检查管理器是否还活着,在我能想到的几乎所有方面都会更容易和更好的解决方案。


在聊天中讨论后,我们意识到最简单的方法就是抑制从sys.exit() 抛出的SystemExit。我在 CPython 错误跟踪器上打开了一个 bug report,以防止 sys.exit()。请记住,服务器实际上不会关闭,因为它在不同的线程上运行。在 stdlib 中使用 .server().serve_forever() 的整个建议看起来充其量是可疑的。

如果您想立即关闭服务器,请在捕获异常后调用Server.listener.close()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-20
    • 2012-09-27
    • 1970-01-01
    • 2020-09-08
    相关资源
    最近更新 更多