python - 为什么将 Python 系统类与自定义类合并不如 Hook 导入机制可取?

标签 python sockets networking distributed-system

我正在从事一个旨在使用部分排序信息来扩充 Python 套接字消息的项目。我正在构建的库是用 Python 编写的,需要插入到通过套接字函数发送的现有系统消息中。

我已经阅读了一些资源,即@Omnifarious 对这个问题的回答 python-importing-from-builtin-library-when-module-with-same-name-exist

There is an extremely ugly and horrible thing you can do that does not involve hooking the import mechanism. This is something you should probably not do, but it will likely work. It turns your calendar module into a hybrid of the system calendar module and your calendar module.

我已经实现了导入机制的解决方案,但我们认为这不是我们想要的方向,因为它太依赖环境了。将类合并为混合类而不是依赖导入机制的解决方案在我看来是最好的方法。

为什么混合动力车被称为丑陋而可怕的解决方案?我想开始在我的项目中实现它,但我对警告很谨慎。这看起来确实有点 hackish,但由于它是安装脚本的一部分,运行一次不是可以吗?

这是一个代码片段,其中插入需要在发送之前拦截套接字消息:

class vector_clock:

  def __init__(self):
   """
   Initiate the clock with the object
   """
   self.clock = [0,0]

  def sendMessage(self):
   """
   Send Message to the server
   """
   self.msg = "This is the test message to that will be interposed on"
   self.vector_clock.increment(0) # We are clock position 0

   # Some extraneous formatting details removed for brevity….
   # connectAndSend needs interpositioning to include the vector clock

   self.client.connectAndSend(totalMsg);
   self.client.s.close()

最佳答案

根据我对您帖子的理解,您希望修改现有的套接字库以将您自己的功能注入(inject)其中。

是的,这是完全可行的,甚至可能是解决您的问题的最简单方法,但您必须考虑您正在做的事情的所有影响。

最重要的一点是,您不仅要为自己修改套接字,还要为在进程的任何部分 中运行的任何使用套接字库的东西修改,除非它使用自己的类加载器。我知道您可能正在使用一些使用套接字的现有库,并且您想将此功能注入(inject)其中,但这会影响一切。

由此你要考虑一个问题:你的改变是否100%向后兼容。除非你能保证你知道你的进程使用的任何库的套接字的每一个用例(提示:你不能),否则你需要确保它完全保留所有现有功能或否则在某个地方某个核心库中的东西会神秘地破坏,你将不知道为什么也没有办法调试它。 100% 向后兼容(或尽可能接近)的一个例子是注入(inject)一个装饰器,它将计时信息保存到您自己的模块之一。

如果您完全理解这一点并且仍然认为您的解决方案是一个好的解决方案,那么我会说“坚持下去”。但是,您是否考虑过任何替代方案?

如果您只需要为您使用的一组特定库注入(inject)此功能,那么我建议您做一些类似修补的事情:https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch

您可以子类化您想要修改的任何核心库,然后修补该库以使用您的类。从本质上讲,补丁所做的是修改目标模块中使用的全局绑定(bind),以使用与最初使用的类/模块不同的类/模块。

附言。我不认为你的情况需要 Hook 导入机制。

关于python - 为什么将 Python 系统类与自定义类合并不如 Hook 导入机制可取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23766252/

相关文章:

Python 模块不会安装

python - 将新列从 Pandas 添加到 SQLite 表的工作流程

c++ - 编写客户端和服务器,UDP

linux - 如何找到linux的套接字缓冲区大小

mysql - 不小心暴露了端口?

python - 替换字符串中的句点 (".")

java - 如何解析xls文件? (已知语言: Python, Java、Lua)

c++ - 将流转换为函数参数以使用 Telnet 和 Ncurses

c# - 用于 ASP.NET 和 Java 的共享 MySQL 数据库

c# - 如何在 C# 控制台应用程序中设置出站/发送 IP 地址?