如何对smbprotocol中SMBDirectoryIO的__init__方法打猴子补丁?
猴子补丁SMBDirectoryIO未生效的原因及解决办法
你的补丁代码逻辑本身没问题,但没生效的核心原因是模块内部的引用时机问题:
如果smbclient._os模块已经在你打补丁之前,就把SMBDirectoryIO导入到了自己的本地命名空间,那你替换smbclient._io里的类,不会影响_os里已经存在的引用,listdir调用的还是原来的类。
下面是几种解决办法:
1. 提前打补丁(优先推荐)
确保补丁代码在任何导入smbclient._os或调用listdir之前执行,这样后续模块导入的就是你补丁后的类:
# 第一步:先打补丁 import smbclient._io class SMBDirectoryIOPatched(smbclient._io.SMBDirectoryIO): def __init__(self, path, mode, *args, **kwargs): super().__init__(path, mode + "a", *args, **kwargs) smbclient._io.SMBDirectoryIO = SMBDirectoryIOPatched # 第二步:再导入并使用相关功能 from smbclient import listdir # 调用listdir时就会使用补丁后的类了
2. 替换目标模块的本地引用
如果无法调整导入顺序,直接替换smbclient._os里已经导入的SMBDirectoryIO引用:
import smbclient._io import smbclient._os class SMBDirectoryIOPatched(smbclient._io.SMBDirectoryIO): def __init__(self, path, mode, *args, **kwargs): super().__init__(path, mode + "a", *args, **kwargs) # 同时替换两个模块中的类引用 smbclient._io.SMBDirectoryIO = SMBDirectoryIOPatched smbclient._os.SMBDirectoryIO = SMBDirectoryIOPatched
3. 验证补丁是否生效
可以在补丁类的__init__方法中添加打印语句,快速确认是否被调用:
class SMBDirectoryIOPatched(smbclient._io.SMBDirectoryIO): def __init__(self, path, mode, *args, **kwargs): print(f"补丁已触发!原mode: {mode},修改后mode: {mode + 'a'}") super().__init__(path, mode + "a", *args, **kwargs)
内容的提问来源于stack exchange,提问作者rwb
相关产品推荐
相关产品推荐

