假设我有一个第三方库,我不允许修改。假设,它被称为Fabric,但这只是解释症状的重要因素。
该脚本处理现有文件列表以使用fabric.operations.get
来获取它们,fabric.sftp.SFTP.get
又调用fabric.sftp.SFTP.get
。使用Warning: get() encountered an exception while downloading ... Underlying exception: Permission denied
生成了一些Permission denied
。我注意到实现太旧了,并且将该函数的实现交换为使用sudo来解决import fabric.sftp
def sftpget(....same args as in current implementation....):
...here I pasted fabric.sftp.SFTP.get from the Internet
# swapping the implementation
fabric.sftp.SFTP.get=sftpget
的问题:
fabric.operations.get
这在99.999%的案例中有效。但是获取三个文件仍会导致相同的错误。我试着看看是否是由其他代码路径引起的,但是打印该字符串的唯一地方是except:
/usr/lib/python2.6/site-packages/
子句{grepped get() encountered an exception while downloading
Permission denied
) 。我试图将该函数交换为将打印异常的堆栈跟踪的实现,但我仍然只获得fabric.operations.get
消息,并且没有堆栈跟踪。
在这种情况下看起来函数不会被交换。
某些调用使用原始fabric.sftp.SFTP.get
的原因可能是什么(因为我没有看到打印的堆栈跟踪)(可能还有未修补的{{1}},因为看起来sudo修复不是正在使用 - 我手动检查那些操作可以在那些文件上完成)?
答案 0 :(得分:0)
在导入期间,在替换get函数之前,其他一段代码可能会保存对get函数的引用,例如:
class a():
def __init__(self,getter):
self.getter=getter
b=a(sftp.SFTP.get)
然后,类a仍将保留对旧代码的引用,尽管它在命名空间中被您替换。