本文介绍了什么可能导致 python 模块被导入两次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,python 模块永远不会导入两次,即模块中的代码仅在第一次导入时执行.后续的导入语句只是将模块添加到导入的范围内.

As far as I understand, a python module is never imported twice, i.e. the code in the module only gets executed the first time it is imported. Subsequent import statements just add the module to the scope of the import.

我有一个名为TiledConvC3D.py"的模块,但它似乎被多次导入.我使用 pdb 在这个模块的代码顶部打印堆栈.

I have a module called "TiledConvC3D.py" that seems to be imported multiple times though. I use pdb to print the stack at the top of the code for this module.

这是第一次执行模块时堆栈跟踪的结尾:

Here is the end of the stack trace from the first time the module is executed:

File "<anonymized>/python_modules/Theano/theano/gof/cmodule.py", line 328, in refresh
  key = cPickle.load(open(key_pkl, 'rb'))
File "<anonymized>/ops/TiledConvG3D.py", line 565, in <module>
  import TiledConvC3D
File "<anonymized>/ops/TiledConvC3D.py", line 18, in <module>
  pdb.traceback.print_stack()

它继续执行多次.但是,第二次调用的完整堆栈跟踪没有显示对 reload 的任何调用,因此不应发生这些执行:

It goes on to be executed several more times. However, the complete stack trace for the second time it is called does not show any calls to reload, so these executions should not be occurring:

File "sup_train_conj_grad.py", line 103, in <module>
  dataset = Config.get_dataset(dataset_node)
File "<anonymized>/Config.py", line 279, in get_dataset
  from datasets import NewWiskott
File "<anonymized>/datasets/NewWiskott.py", line 16, in <module>
  normalizer_train = video.ContrastNormalizer3D(sigma, global_per_frame = False, input_is_5d = True)
File "<anonymized>/util/video.py", line 204, in __init__
  self.f = theano.function([input],output)
File "<anonymized>/python_modules/Theano/theano/compile/function.py", line 105, in function
  allow_input_downcast=allow_input_downcast)
File "<anonymized>/python_modules/Theano/theano/compile/pfunc.py", line 270, in pfunc
  accept_inplace=accept_inplace, name=name)
File "<anonymized>/python_modules/Theano/theano/compile/function_module.py", line 1105, in orig_function
  fn = Maker(inputs, outputs, mode, accept_inplace = accept_inplace).create(defaults)
File "/u/goodfeli/python_modules/Theano/theano/compile/function_module.py", line 982, in create
  _fn, _i, _o = self.linker.make_thunk(input_storage = input_storage_lists)
File "<anonymized>/python_modules/Theano/theano/gof/link.py", line 321, in make_thunk
  output_storage = output_storage)[:3]
File "<anonymized>/python_modules/Theano/theano/gof/cc.py", line 1178, in make_all
  output_storage = node_output_storage)
File "<anonymized>/python_modules/Theano/theano/gof/cc.py", line 774, in make_thunk
  cthunk, in_storage, out_storage, error_storage = self.__compile__(input_storage, output_storage)
File "<anonymized>/python_modules/Theano/theano/gof/cc.py", line 723, in __compile__
  output_storage)
File "<anonymized>/python_modules/Theano/theano/gof/cc.py", line 1037, in cthunk_factory
  module = get_module_cache().module_from_key(key=key, fn=self.compile_cmodule)
File "<anonymized>/python_modules/Theano/theano/gof/cc.py", line 59, in get_module_cache
  return cmodule.get_module_cache(config.compiledir)
File "<anonymized>/python_modules/Theano/theano/gof/cmodule.py", line 576, in get_module_cache
  _module_cache = ModuleCache(dirname, force_fresh=force_fresh)
File "<anonymized>/python_modules/Theano/theano/gof/cmodule.py", line 268, in __init__
  self.refresh()
File "<anonymized>/python_modules/Theano/theano/gof/cmodule.py", line 326, in refresh
  key = cPickle.load(open(key_pkl, 'rb'))
File "<anonymized>/ops/TiledConvV3D.py", line 504, in <module>
  import TiledConvG3D
File "<anonymized>/ops/TiledConvG3D.py", line 565, in <module>
  import TiledConvC3D
File "<anonymized>/ops/TiledConvC3D.py", line 22, in <module>
  pdb.traceback.print_stack()

此外,我还检查了 __builtin__.__import__ 的 id.在我的主脚本的最开始,我导入 __builtin__ 并在执行任何其他导入之前打印 id(__builtin__.__import__) .我还在多次导入的模块中打印了 id(__builtin__.import__),并且 id 的值没有改变.

Moreover, I also check the id of __builtin__.__import__ . At the very start of my main script, I import __builtin__ and print id(__builtin__.__import__) before doing any other imports. I also print id(__builtin__.import__) from inside my module that is being imported multiple times, and the value of the id does not change.

除了调用 reload 和覆盖 __builtin__.__import__ 之外,还有其他机制可以解释我的模块被多次加载吗?

Are there other mechanisms besides calling reload and overriding __builtin__.__import__ that could explain my module getting loaded multiple times?

推荐答案

如果 Python 模块在路径中被发现两次,则该模块可以被导入两次.例如,假设您的项目如下所示:

A Python module can be imported twice if the module is found twice in the path. For example, say your project is laid out like so:

  • 源代码/
    • package1/
      • 垃圾邮件.py
      • eggs.py

      假设您的 PYTHONPATH (sys.path) 包括 src 和 src/package1:

      Suppose your PYTHONPATH (sys.path) includes src and src/package1:

      PYTHONPATH=/path/to/src:/path/to/src/package1
      

      如果是这样,您可以像这样导入同一个模块两次:

      If that's the case, you can import the same module twice like this:

      from package1 import spam
      import spam
      

      Python 会认为它们是不同的模块.这是怎么回事?

      And Python will think they are different modules. Is that what's going on?

      此外,根据下面的讨论(对于搜索此问题的用户),可以将模块导入两次的另一种方法是,如果在第一次导入的中途出现异常.例如,如果垃圾邮件导入鸡蛋,但导入鸡蛋导致模块内异常,则可以再次导入.

      Also, per the discussion below (for users searching this question), another way a module can be imported twice is if there is an exception midway through the first import. For example, if spam imports eggs, but importing eggs results in an exception inside the module, it can be imported again.

      这篇关于什么可能导致 python 模块被导入两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 07:49