Python:如何使用包含在包外的修改版本覆盖包中的一个模块?

zlo*_*ady 13 python django

我想用我自己的模块版本更新python包中的一个模块,具有以下条件:

  • 我希望我更新的模块存在于原始包之外(因为我无法访问包源,或者因为我想将我的本地修改保存在单独的repo中等).
  • 我想要import引用原始包/模块的语句来解析我的本地模块

这是我想用django的细节做的一个例子,因为这就是我出现这个问题的地方:

说这是我的项目结构

django/
  ... the original, unadulterated django package ...
local_django/
  conf/
    settings.py
myproject/
  __init__.py
  myapp/
    myfile.py
Run Code Online (Sandbox Code Playgroud)

然后在myfile.py中

# These imports should fetch modules from the original django package
from django import models
from django.core.urlresolvers import reverse

# I would like this following import statement to grab a custom version of settings 
# that I define in local_django/conf/settings.py 
from django.conf import settings

def foo():
  return settings.some_setting
Run Code Online (Sandbox Code Playgroud)

我可以用__import__声明做一些魔术myproject/__init__.py来完成这个吗?是否有更"pythonic"的方法来实现这一目标?

更新 - 为什么我要这样做

这是我觉得这很有意义的场景.

  • 我正在全球预装django的服务器上启动一个django支持的网站.在这种情况下,我无法修改实际的django源.
  • 我的django项目使用第三方可重用应用程序,例如,我不想更改imports所有要导入的应用程序mycustomsettings.我想让可重用的应用程序幸福地无知我已经改变了django.conf.settings的实现.

Tho*_*ard 15

只需在其他任何内容导入之前在sys.modules中设置条目:

import sys
import myreplacement
sys.modules["original"] = myreplacement
Run Code Online (Sandbox Code Playgroud)

然后,当某人"导入原始"时,他们将获得您的版本.

如果要替换子模块,可以这样做:

import sys
import thepackage
sys.modules["thepackage"].submodule = myreplacement
sys.modules["thepackage.submodule"] = myreplacement
Run Code Online (Sandbox Code Playgroud)

然后"from thepackage import submodule"或"import thepackage.submodule"将给出"myreplacement".