从文件路径动态加载模块时,强制python忽略pyc文件

从文件路径动态加载模块时,强制python忽略pyc文件,python,Python,我需要通过运行时已知的filepath(例如“/some/path/to/module.py”)导入python模块,并忽略任何.pyc文件(如果它们存在) 这建议使用imp.load_模块作为解决方案,但这种方法似乎也使用.pyc版本(如果存在) importme.py SOME_SETTING = 4 main.py: import imp if __name__ == '__main__': name = 'importme' openfile, pathname, de

我需要通过运行时已知的filepath(例如“/some/path/to/module.py”)导入python模块,并忽略任何
.pyc
文件(如果它们存在)

这建议使用
imp.load_模块
作为解决方案,但这种方法似乎也使用
.pyc
版本(如果存在)

importme.py

SOME_SETTING = 4
main.py:

import imp
if __name__ == '__main__':
    name = 'importme'
    openfile, pathname, description = imp.find_module(name)
    module = imp.load_module(name, openfile, pathname, description)
    openfile.close()
    print module
执行两次,第一次调用后使用
.pyc
文件:

$ python main.py 
<module 'importme' from '/Users/dbryant/temp/pyc/importme.py'>

$ python main.py 
<module 'importme' from '/Users/dbryant/temp/pyc/importme.pyc'>
$python main.py
$python main.py
不幸的是,
imp.load\u source
具有相同的行为(来自文档):

请注意,如果一个正确匹配的字节编译文件(后缀为.pyc 或.pyo),则将使用它而不是解析给定的源 文件

使每个包含目录的脚本只读是我所知道的唯一解决方案(首先防止生成
.pyc
文件),但如果可能的话,我宁愿避免


(注意:使用python 2.7)

改用包含python源代码的zip文件怎么样:

import sys
sys.path.insert("package.zip")

您可以将包含.py文件的目录标记为只读。

load\u source
为我做了正确的事情,即

dir, name = os.path.split(path)
mod = imp.load_source(name, path)
即使pyc文件可用,也使用.py变量-名称以python3下的
.py
结尾。显而易见的解决方案是在加载文件之前删除所有的.pyc文件-但是如果您运行多个程序实例,竞争条件可能会有问题

还有一种可能性:Iirc您可以让python从内存中解释文件,即使用普通的文件API加载文件,然后编译内存中的变量。比如:

path = "some Filepath.py"
with open(path, "r", encoding="utf-8") as file:
    data = file.read()
exec(compile(data, "<string>", "exec")) # fair use of exec, that's a first!
path=“some Filepath.py”
打开(路径“r”,编码=“utf-8”)作为文件:
data=file.read()
exec(编译(数据,“,”exec”)#合理使用exec,这是第一次!

为什么要阻止使用pyc文件?它将只使用与py相同的pyc文件。如果您更改py,它将重新编译pyc。@falmari它很复杂。这与以下事实有关:不同类型的机器正在访问同一组python文件,并且它们似乎产生了相同源代码的不兼容字节编译(例如,机器A生成的pyc无法被机器B读取,导致机器B无法动态导入模块);是的,所有的机器都在使用解释器二进制。不同的机器编写不同字节码的唯一原因是它们运行的解释器版本不同。很有趣,但对于我的用例来说,效果并不好。我正在动态加载的模块是设置文件,需要易于人类阅读和编辑。您还可以查看使用PythontWriteByteCode环境变量。这一点很好。这也行,但唯一导致问题的pyc文件是那些动态加载了
imp
的文件,我希望在其他可用的情况下仍能使用字节码版本。可以使用sys.dont_write_bytecode设置环境变量,导入您的模块,然后将字节码设置更改回实现此目的的方式?@Sanjamal谢谢,如果您的建议有效,那么是的,对我来说就足够了。我会测试它。是的,我知道(见问题的底部),但这并不能真正解决问题,而且非常不方便,因为我仍然需要写入包含日志、输出等的目录。我不知道您的确切情况是什么,但我通常尽量避免将数据写入到包含代码的同一目录中。原则上我同意,但是Python设置文件模糊了数据和代码之间的界限(例如,在Django中非常常见的做法),我甚至没有考虑执行设置文件/模块内容。这对我来说也是一个可行的解决方案。