尽管存在此导入错误,但使用 python 进行 sftp 文件传输工作正常。如何消除这个错误?

发布于 2025-01-12 02:48:08 字数 1266 浏览 13 评论 0原文

我有这个 python 函数通过 sftp 上传文件。效果很好。

def sftp_upload(destination, username, password,
                     remote_loc, source_file):
    import pysftp
    with pysftp.Connection(destination, username,
                           password, log="pysftp.log") as sftp:
        sftp.cwd(remote_loc)
        sftp.put(source_file)

    sftp.close()
    return None

该代码按预期工作。但是,我总是在最后收到此错误 ImportError: sys.meta_path is None, Python is likely shutdown

如何消除这个错误?我也很困惑为什么尽管出现错误,代码仍能顺利运行到最后。

在日志文件中,我看到以下内容;

INF [20220304-18:49:14.727] thr=2   paramiko.transport.sftp: [chan 0] sftp session closed.
DEB [20220304-18:49:14.727] thr=2   paramiko.transport: [chan 0] EOF sent (0)
DEB [20220304-18:49:14.728] thr=1   paramiko.transport: EOF in transport thread

这是堆栈跟踪;

Exception ignored in: <function Connection.__del__ at 0x000001A8B08765E0>
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\site-packages\pysftp\__init__.py", line 1013, in __del__
  File "C:\ProgramData\Anaconda3\lib\site-packages\pysftp\__init__.py", line 795, in close
ImportError: sys.meta_path is None, Python is likely shutting down

我正在使用 python v3.9

I have this python function to upload file through sftp. It works fine.

def sftp_upload(destination, username, password,
                     remote_loc, source_file):
    import pysftp
    with pysftp.Connection(destination, username,
                           password, log="pysftp.log") as sftp:
        sftp.cwd(remote_loc)
        sftp.put(source_file)

    sftp.close()
    return None

The code works as expected. However, I always receive this error at the end ImportError: sys.meta_path is None, Python is likely shutting down.

How to remove this error? I'm also puzzled why code runs smoothly to the end despite the error.

In the log file, I saw the following;

INF [20220304-18:49:14.727] thr=2   paramiko.transport.sftp: [chan 0] sftp session closed.
DEB [20220304-18:49:14.727] thr=2   paramiko.transport: [chan 0] EOF sent (0)
DEB [20220304-18:49:14.728] thr=1   paramiko.transport: EOF in transport thread

Here's the stack trace;

Exception ignored in: <function Connection.__del__ at 0x000001A8B08765E0>
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\site-packages\pysftp\__init__.py", line 1013, in __del__
  File "C:\ProgramData\Anaconda3\lib\site-packages\pysftp\__init__.py", line 795, in close
ImportError: sys.meta_path is None, Python is likely shutting down

I am using python v3.9

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

〆凄凉。 2025-01-19 02:48:08

注意:函数外部的 import pysftp 以某种方式为我解决了问题。

Note: import pysftp outside the function somehow resolves the issue for me. ????


It's a bug in pysftp==0.2.9.

You can fix it by overriding close() to only run once:

class SFTPConnection(pysftp.Connection):
    def close(self):
        if getattr(self, '_closed', False):
            return
        self._closed = True
        super().close()

Usage:

# with pysftp.Connection(destination, username, password=password, log="pysftp.log") as sftp:  # -
with SFTPConnection(destination, username, password=password, log="pysftp.log") as sftp:       # +

References:

祁梦 2025-01-19 02:48:08

看起来您的程序在 sftp 对象被垃圾收集之前结束。
然后,在程序拆卸过程中调用 sftp.__del__ 方法,这导致了错误。

来自 pysftp.py 代码:

def __del__(self):
    """Attempt to clean up if not explicitly closed."""
    self.close()

我个人认为应该考虑作为 pysftp 中的一个错误 项目。

我可以想到两种解决方法:

  1. 重写 __del__ 方法:

    pysftp.Connection.__del__ = lambda x:无

  2. (不太推荐 - 效率较低)显式删除sftp对象并触发垃圾收集:

    <代码>del sftp;导入气相色谱; gc.collect() 就在 with

    之后

It looks like your program ends before the sftp object is garbage-collected.
Then, the sftp.__del__ method is called at the middle of the program's teardown, which is causing the error.

From pysftp.py code:

def __del__(self):
    """Attempt to clean up if not explicitly closed."""
    self.close()

I personally think that it should be considered as a bug in the pysftp project.

I can think of two workarounds:

  1. Override the __del__ method:

    pysftp.Connection.__del__ = lambda x: None

  2. (Less recomended - less efficient) Explicitly delete the sftp object and trigger garbage collection:

    del sftp; import gc; gc.collect() right after the with block

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文