程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

About a hole in Python -- reload causes module reset

編輯:Python

In many cases, we need to dynamically introduce a library , For example, we need to introduce a library on both the server and the client , Their file names are the same , How to cache them at runtime ?
Here is an interesting example , The file structure is as follows :

# testlib1/testModulenum = 1
# testlib2/testModulenum = 2
# -*- coding: utf-8 -*-# At this point, there is a requirement as follows # We need to introduce two files with the same file name python file # And cannot be static import Only code dynamic can be called reloadimport importlibimport osimport sys# situation 1class loadModuleCS(object): """ Import the server and client Libraries """ def __init__(self): super(loadModuleCS, self).__init__() self.clientModule = None self.serverModule = None self.loadClientModule() self.loadServerModule() def _loadModule(self, path): """ load path Module under """ name = os.path.basename(path) path = path.replace(name, "") sys.path.insert(0, path) module = importlib.import_module(name.split('.')[0]) importlib.reload(module) print(" In the database num by : ", module.num) sys.path.pop(0) return module def loadClientModule(self): path = r"F:\PythonXSLWorkSpace\PythonBaseUse\pythonBug\1error\testlib1\testModule.py" self.clientModule = self._loadModule(path) def loadServerModule(self): path = r"F:\PythonXSLWorkSpace\PythonBaseUse\pythonBug\1error\testlib2\testModule.py" self.serverModule = self._loadModule(path)loader = loadModuleCS()print(loader.clientModule.num)print(loader.serverModule.num)

reflection

The running result is as above , Think about a thing : The library is correct when we import , Then why do we reintroduce clientModule and serverModule Take it out and take the value inside , But it's wrong ?
Let's do one thing :

loader = loadModuleCS()print(loader.clientModule.num)print(loader.serverModule.num)print(loader.clientModule is loader.serverModule)

The results are as follows :

Now it's clear at a glance , At this time they are actually the same thing ! in other words clientModule and serverModule Currently, it refers to the same object !!why?????
We all know ,python The imported libraries are stored in sys.modules in , sys.modules It's a dictionary , The imported modules are stored , Could this be the reason ?

verification

class loadModuleCS(object): """ Import the server and client Libraries """ def __init__(self): super(loadModuleCS, self).__init__() self.clientModule = None self.serverModule = None self.loadClientModule() self.loadServerModule() def _loadModule(self, path): """ load path Module under """ name = os.path.basename(path) path = path.replace(name, "") sys.path.insert(0, path) module = importlib.import_module(name.split('.')[0]) importlib.reload(module) print(" In the database num by : ", module.num) print(sys.modules["testModule"]) sys.path.pop(0) return module def loadClientModule(self): path = r"F:\PythonXSLWorkSpace\PythonBaseUse\pythonBug\1error\testlib1\testModule.py" self.clientModule = self._loadModule(path) def loadServerModule(self): path = r"F:\PythonXSLWorkSpace\PythonBaseUse\pythonBug\1error\testlib2\testModule.py" self.serverModule = self._loadModule(path)loader = loadModuleCS()print(sys.modules["testModule"])print(loader.clientModule.num)print(loader.serverModule.num)print(loader.clientModule is loader.serverModule)print(loader.clientModule is sys.modules["testModule"], loader.serverModule is sys.modules["testModule"])

The output is as follows

It proves our conjecture , here clientModule and serverModule Currently, it refers to the same object

Revise the plan

 def _loadModule(self, path): """ load path Module under """ name = os.path.basename(path) path = path.replace(name, "") sys.path.insert(0, path) moduleName = name.split('.')[0] if moduleName in sys.modules: sys.modules.pop(moduleName) module = importlib.import_module(moduleName) importlib.reload(module) print(" In the database num by : ", module.num) print(sys.modules["testModule"]) sys.path.pop(0) return module

This is what we expected , clientModule and serverModule Reference to two different libraries !

author : Change in adversity

Game programming , A game development favorite ~

If the picture is not displayed for a long time , Please use Chrome Kernel browser .


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved