dill.dump_session 无法使用 getpass
dill.dump_session not working with getpass
我有一个 Jupyter 笔记本,我想使用 dill.dump_session
保存其状态,但是如果笔记本使用 getpass
模块,该函数会抛出错误。有什么办法解决这个问题吗?
我理解不转储密码的意义,但我仍然想保存所有其他变量,而无需手动遍历所有变量。
这是我的代码的玩具示例:
import dill
from getpass import getpass
dill.dump_session('../session_dump/sess_test.pkl')
这是我得到的错误:
TypeError Traceback (most recent call last)
<ipython-input-8-5758b730705e> in <module>
----> 1 dill.dump_session('../session_dump/sess_test.pkl')
~\Anaconda3\lib\site-packages\dill\_dill.py in dump_session(filename, main, byref)
391 pickler._recurse = False # disable pickling recursion for globals
392 pickler._session = True # is best indicator of when pickling a session
--> 393 pickler.dump(main)
394 finally:
395 if f is not filename: # If newly opened file
~\Anaconda3\lib\pickle.py in dump(self, obj)
435 if self.proto >= 4:
436 self.framer.start_framing()
--> 437 self.save(obj)
438 self.write(STOP)
439 self.framer.end_framing()
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
502 f = self.dispatch.get(t)
503 if f is not None:
--> 504 f(self, obj) # Call unbound method with explicit self
505 return
506
~\Anaconda3\lib\site-packages\dill\_dill.py in save_module(pickler, obj)
1267 + ["__builtins__", "__loader__"]]
1268 pickler.save_reduce(_import_module, (obj.__name__,), obj=obj,
-> 1269 state=_main_dict)
1270 log.info("# M1")
1271 else:
~\Anaconda3\lib\pickle.py in save_reduce(self, func, args, state, listitems, dictitems, obj)
660
661 if state is not None:
--> 662 save(state)
663 write(BUILD)
664
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
502 f = self.dispatch.get(t)
503 if f is not None:
--> 504 f(self, obj) # Call unbound method with explicit self
505 return
506
~\Anaconda3\lib\site-packages\dill\_dill.py in save_module_dict(pickler, obj)
900 # we only care about session the first pass thru
901 pickler._session = False
--> 902 StockPickler.save_dict(pickler, obj)
903 log.info("# D2")
904 return
~\Anaconda3\lib\pickle.py in save_dict(self, obj)
854
855 self.memoize(obj)
--> 856 self._batch_setitems(obj.items())
857
858 dispatch[dict] = save_dict
~\Anaconda3\lib\pickle.py in _batch_setitems(self, items)
880 for k, v in tmp:
881 save(k)
--> 882 save(v)
883 write(SETITEMS)
884 elif n:
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
502 f = self.dispatch.get(t)
503 if f is not None:
--> 504 f(self, obj) # Call unbound method with explicit self
505 return
506
~\Anaconda3\lib\site-packages\dill\_dill.py in save_instancemethod0(pickler, obj)
1076 log.info("Me: %s" % obj) #XXX: obj.__dict__ handled elsewhere?
1077 if PY3:
-> 1078 pickler.save_reduce(MethodType, (obj.__func__, obj.__self__), obj=obj)
1079 else:
1080 pickler.save_reduce(MethodType, (obj.im_func, obj.im_self,
~\Anaconda3\lib\pickle.py in save_reduce(self, func, args, state, listitems, dictitems, obj)
636 else:
637 save(func)
--> 638 save(args)
639 write(REDUCE)
640
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
502 f = self.dispatch.get(t)
503 if f is not None:
--> 504 f(self, obj) # Call unbound method with explicit self
505 return
506
~\Anaconda3\lib\pickle.py in save_tuple(self, obj)
769 if n <= 3 and self.proto >= 2:
770 for element in obj:
--> 771 save(element)
772 # Subtle. Same as in the big comment below.
773 if id(obj) in memo:
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
547
548 # Save the reduce() output and finally memoize the object
--> 549 self.save_reduce(obj=obj, *rv)
550
551 def persistent_id(self, obj):
~\Anaconda3\lib\pickle.py in save_reduce(self, func, args, state, listitems, dictitems, obj)
660
661 if state is not None:
--> 662 save(state)
663 write(BUILD)
664
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
502 f = self.dispatch.get(t)
503 if f is not None:
--> 504 f(self, obj) # Call unbound method with explicit self
505 return
506
~\Anaconda3\lib\site-packages\dill\_dill.py in save_module_dict(pickler, obj)
900 # we only care about session the first pass thru
901 pickler._session = False
--> 902 StockPickler.save_dict(pickler, obj)
903 log.info("# D2")
904 return
~\Anaconda3\lib\pickle.py in save_dict(self, obj)
854
855 self.memoize(obj)
--> 856 self._batch_setitems(obj.items())
857
858 dispatch[dict] = save_dict
~\Anaconda3\lib\pickle.py in _batch_setitems(self, items)
880 for k, v in tmp:
881 save(k)
--> 882 save(v)
883 write(SETITEMS)
884 elif n:
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
502 f = self.dispatch.get(t)
503 if f is not None:
--> 504 f(self, obj) # Call unbound method with explicit self
505 return
506
~\Anaconda3\lib\site-packages\dill\_dill.py in save_module_dict(pickler, obj)
900 # we only care about session the first pass thru
901 pickler._session = False
--> 902 StockPickler.save_dict(pickler, obj)
903 log.info("# D2")
904 return
~\Anaconda3\lib\pickle.py in save_dict(self, obj)
854
855 self.memoize(obj)
--> 856 self._batch_setitems(obj.items())
857
858 dispatch[dict] = save_dict
~\Anaconda3\lib\pickle.py in _batch_setitems(self, items)
880 for k, v in tmp:
881 save(k)
--> 882 save(v)
883 write(SETITEMS)
884 elif n:
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
547
548 # Save the reduce() output and finally memoize the object
--> 549 self.save_reduce(obj=obj, *rv)
550
551 def persistent_id(self, obj):
~\Anaconda3\lib\pickle.py in save_reduce(self, func, args, state, listitems, dictitems, obj)
660
661 if state is not None:
--> 662 save(state)
663 write(BUILD)
664
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
502 f = self.dispatch.get(t)
503 if f is not None:
--> 504 f(self, obj) # Call unbound method with explicit self
505 return
506
~\Anaconda3\lib\site-packages\dill\_dill.py in save_module_dict(pickler, obj)
900 # we only care about session the first pass thru
901 pickler._session = False
--> 902 StockPickler.save_dict(pickler, obj)
903 log.info("# D2")
904 return
~\Anaconda3\lib\pickle.py in save_dict(self, obj)
854
855 self.memoize(obj)
--> 856 self._batch_setitems(obj.items())
857
858 dispatch[dict] = save_dict
~\Anaconda3\lib\pickle.py in _batch_setitems(self, items)
885 k, v = tmp[0]
886 save(k)
--> 887 save(v)
888 write(SETITEM)
889 # else tmp is empty, and we're done
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
547
548 # Save the reduce() output and finally memoize the object
--> 549 self.save_reduce(obj=obj, *rv)
550
551 def persistent_id(self, obj):
~\Anaconda3\lib\pickle.py in save_reduce(self, func, args, state, listitems, dictitems, obj)
660
661 if state is not None:
--> 662 save(state)
663 write(BUILD)
664
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
502 f = self.dispatch.get(t)
503 if f is not None:
--> 504 f(self, obj) # Call unbound method with explicit self
505 return
506
~\Anaconda3\lib\site-packages\dill\_dill.py in save_module_dict(pickler, obj)
900 # we only care about session the first pass thru
901 pickler._session = False
--> 902 StockPickler.save_dict(pickler, obj)
903 log.info("# D2")
904 return
~\Anaconda3\lib\pickle.py in save_dict(self, obj)
854
855 self.memoize(obj)
--> 856 self._batch_setitems(obj.items())
857
858 dispatch[dict] = save_dict
~\Anaconda3\lib\pickle.py in _batch_setitems(self, items)
880 for k, v in tmp:
881 save(k)
--> 882 save(v)
883 write(SETITEMS)
884 elif n:
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
522 reduce = getattr(obj, "__reduce_ex__", None)
523 if reduce is not None:
--> 524 rv = reduce(self.proto)
525 else:
526 reduce = getattr(obj, "__reduce__", None)
~\Anaconda3\lib\site-packages\zmq\backend\cython\socket.cp37-win_amd64.pyd in zmq.backend.cython.socket.Socket.__reduce_cython__()
TypeError: no default __reduce__ due to non-trivial __cinit__
正如所讨论的 here 问题来自 getpass 引用 sys.stdout,它在 jupyter 笔记本中 运行 时引用了 zmq 套接字。事实上,在常规 .py 脚本中尝试没有问题。
在笔记本中使用它的一个简单解决方案是在 dill.dump_session
之前添加 del getpass
,例如:
import dill
from getpass import getpass
pwd = getpass("Insert password: ")
del getpass
dill.dump_session('../session_dump/sess_test.pkl')
我有一个 Jupyter 笔记本,我想使用 dill.dump_session
保存其状态,但是如果笔记本使用 getpass
模块,该函数会抛出错误。有什么办法解决这个问题吗?
我理解不转储密码的意义,但我仍然想保存所有其他变量,而无需手动遍历所有变量。
这是我的代码的玩具示例:
import dill
from getpass import getpass
dill.dump_session('../session_dump/sess_test.pkl')
这是我得到的错误:
TypeError Traceback (most recent call last)
<ipython-input-8-5758b730705e> in <module>
----> 1 dill.dump_session('../session_dump/sess_test.pkl')
~\Anaconda3\lib\site-packages\dill\_dill.py in dump_session(filename, main, byref)
391 pickler._recurse = False # disable pickling recursion for globals
392 pickler._session = True # is best indicator of when pickling a session
--> 393 pickler.dump(main)
394 finally:
395 if f is not filename: # If newly opened file
~\Anaconda3\lib\pickle.py in dump(self, obj)
435 if self.proto >= 4:
436 self.framer.start_framing()
--> 437 self.save(obj)
438 self.write(STOP)
439 self.framer.end_framing()
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
502 f = self.dispatch.get(t)
503 if f is not None:
--> 504 f(self, obj) # Call unbound method with explicit self
505 return
506
~\Anaconda3\lib\site-packages\dill\_dill.py in save_module(pickler, obj)
1267 + ["__builtins__", "__loader__"]]
1268 pickler.save_reduce(_import_module, (obj.__name__,), obj=obj,
-> 1269 state=_main_dict)
1270 log.info("# M1")
1271 else:
~\Anaconda3\lib\pickle.py in save_reduce(self, func, args, state, listitems, dictitems, obj)
660
661 if state is not None:
--> 662 save(state)
663 write(BUILD)
664
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
502 f = self.dispatch.get(t)
503 if f is not None:
--> 504 f(self, obj) # Call unbound method with explicit self
505 return
506
~\Anaconda3\lib\site-packages\dill\_dill.py in save_module_dict(pickler, obj)
900 # we only care about session the first pass thru
901 pickler._session = False
--> 902 StockPickler.save_dict(pickler, obj)
903 log.info("# D2")
904 return
~\Anaconda3\lib\pickle.py in save_dict(self, obj)
854
855 self.memoize(obj)
--> 856 self._batch_setitems(obj.items())
857
858 dispatch[dict] = save_dict
~\Anaconda3\lib\pickle.py in _batch_setitems(self, items)
880 for k, v in tmp:
881 save(k)
--> 882 save(v)
883 write(SETITEMS)
884 elif n:
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
502 f = self.dispatch.get(t)
503 if f is not None:
--> 504 f(self, obj) # Call unbound method with explicit self
505 return
506
~\Anaconda3\lib\site-packages\dill\_dill.py in save_instancemethod0(pickler, obj)
1076 log.info("Me: %s" % obj) #XXX: obj.__dict__ handled elsewhere?
1077 if PY3:
-> 1078 pickler.save_reduce(MethodType, (obj.__func__, obj.__self__), obj=obj)
1079 else:
1080 pickler.save_reduce(MethodType, (obj.im_func, obj.im_self,
~\Anaconda3\lib\pickle.py in save_reduce(self, func, args, state, listitems, dictitems, obj)
636 else:
637 save(func)
--> 638 save(args)
639 write(REDUCE)
640
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
502 f = self.dispatch.get(t)
503 if f is not None:
--> 504 f(self, obj) # Call unbound method with explicit self
505 return
506
~\Anaconda3\lib\pickle.py in save_tuple(self, obj)
769 if n <= 3 and self.proto >= 2:
770 for element in obj:
--> 771 save(element)
772 # Subtle. Same as in the big comment below.
773 if id(obj) in memo:
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
547
548 # Save the reduce() output and finally memoize the object
--> 549 self.save_reduce(obj=obj, *rv)
550
551 def persistent_id(self, obj):
~\Anaconda3\lib\pickle.py in save_reduce(self, func, args, state, listitems, dictitems, obj)
660
661 if state is not None:
--> 662 save(state)
663 write(BUILD)
664
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
502 f = self.dispatch.get(t)
503 if f is not None:
--> 504 f(self, obj) # Call unbound method with explicit self
505 return
506
~\Anaconda3\lib\site-packages\dill\_dill.py in save_module_dict(pickler, obj)
900 # we only care about session the first pass thru
901 pickler._session = False
--> 902 StockPickler.save_dict(pickler, obj)
903 log.info("# D2")
904 return
~\Anaconda3\lib\pickle.py in save_dict(self, obj)
854
855 self.memoize(obj)
--> 856 self._batch_setitems(obj.items())
857
858 dispatch[dict] = save_dict
~\Anaconda3\lib\pickle.py in _batch_setitems(self, items)
880 for k, v in tmp:
881 save(k)
--> 882 save(v)
883 write(SETITEMS)
884 elif n:
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
502 f = self.dispatch.get(t)
503 if f is not None:
--> 504 f(self, obj) # Call unbound method with explicit self
505 return
506
~\Anaconda3\lib\site-packages\dill\_dill.py in save_module_dict(pickler, obj)
900 # we only care about session the first pass thru
901 pickler._session = False
--> 902 StockPickler.save_dict(pickler, obj)
903 log.info("# D2")
904 return
~\Anaconda3\lib\pickle.py in save_dict(self, obj)
854
855 self.memoize(obj)
--> 856 self._batch_setitems(obj.items())
857
858 dispatch[dict] = save_dict
~\Anaconda3\lib\pickle.py in _batch_setitems(self, items)
880 for k, v in tmp:
881 save(k)
--> 882 save(v)
883 write(SETITEMS)
884 elif n:
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
547
548 # Save the reduce() output and finally memoize the object
--> 549 self.save_reduce(obj=obj, *rv)
550
551 def persistent_id(self, obj):
~\Anaconda3\lib\pickle.py in save_reduce(self, func, args, state, listitems, dictitems, obj)
660
661 if state is not None:
--> 662 save(state)
663 write(BUILD)
664
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
502 f = self.dispatch.get(t)
503 if f is not None:
--> 504 f(self, obj) # Call unbound method with explicit self
505 return
506
~\Anaconda3\lib\site-packages\dill\_dill.py in save_module_dict(pickler, obj)
900 # we only care about session the first pass thru
901 pickler._session = False
--> 902 StockPickler.save_dict(pickler, obj)
903 log.info("# D2")
904 return
~\Anaconda3\lib\pickle.py in save_dict(self, obj)
854
855 self.memoize(obj)
--> 856 self._batch_setitems(obj.items())
857
858 dispatch[dict] = save_dict
~\Anaconda3\lib\pickle.py in _batch_setitems(self, items)
885 k, v = tmp[0]
886 save(k)
--> 887 save(v)
888 write(SETITEM)
889 # else tmp is empty, and we're done
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
547
548 # Save the reduce() output and finally memoize the object
--> 549 self.save_reduce(obj=obj, *rv)
550
551 def persistent_id(self, obj):
~\Anaconda3\lib\pickle.py in save_reduce(self, func, args, state, listitems, dictitems, obj)
660
661 if state is not None:
--> 662 save(state)
663 write(BUILD)
664
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
502 f = self.dispatch.get(t)
503 if f is not None:
--> 504 f(self, obj) # Call unbound method with explicit self
505 return
506
~\Anaconda3\lib\site-packages\dill\_dill.py in save_module_dict(pickler, obj)
900 # we only care about session the first pass thru
901 pickler._session = False
--> 902 StockPickler.save_dict(pickler, obj)
903 log.info("# D2")
904 return
~\Anaconda3\lib\pickle.py in save_dict(self, obj)
854
855 self.memoize(obj)
--> 856 self._batch_setitems(obj.items())
857
858 dispatch[dict] = save_dict
~\Anaconda3\lib\pickle.py in _batch_setitems(self, items)
880 for k, v in tmp:
881 save(k)
--> 882 save(v)
883 write(SETITEMS)
884 elif n:
~\Anaconda3\lib\pickle.py in save(self, obj, save_persistent_id)
522 reduce = getattr(obj, "__reduce_ex__", None)
523 if reduce is not None:
--> 524 rv = reduce(self.proto)
525 else:
526 reduce = getattr(obj, "__reduce__", None)
~\Anaconda3\lib\site-packages\zmq\backend\cython\socket.cp37-win_amd64.pyd in zmq.backend.cython.socket.Socket.__reduce_cython__()
TypeError: no default __reduce__ due to non-trivial __cinit__
正如所讨论的 here 问题来自 getpass 引用 sys.stdout,它在 jupyter 笔记本中 运行 时引用了 zmq 套接字。事实上,在常规 .py 脚本中尝试没有问题。
在笔记本中使用它的一个简单解决方案是在 dill.dump_session
之前添加 del getpass
,例如:
import dill
from getpass import getpass
pwd = getpass("Insert password: ")
del getpass
dill.dump_session('../session_dump/sess_test.pkl')