net*_*tik 9 python python-3.x python-3.4
/Project
|-- main.py
|--/lib
| |--__init__.py
| |--foo.py
| |--Types.py
Run Code Online (Sandbox Code Playgroud)
/Project/lib已被添加到PYTHONPATH变量中.
Types.py:
class Custom(object):
def __init__(self):
a = 1
b = 2
Run Code Online (Sandbox Code Playgroud)
foo.py:
from Types import Custom
def foo(o):
assert isinstance(o, Custom)
Run Code Online (Sandbox Code Playgroud)
最后,来自main.py:
from lib.Types import Custom
from lib.foo import foo
a = Custom()
foo(a)
Run Code Online (Sandbox Code Playgroud)
现在的问题是,这a是类型lib.foo.Custom,而isinstance调用将检查它是否等于foo.Custom,显然返回false.
如何在不更改库(lib)中的任何内容的情况下避免此问题?
iva*_*eev 11
你不应该同时创建lib一个包并将其添加到PYTHONPATH.这使得可以直接导入其模块lib.,从而使自己失败.
如你看到的,
lib.Types.Custom != Types.Custom
Run Code Online (Sandbox Code Playgroud)
Python搜索导入路径并解析它找到的相应条目.
lib.Types,它将lib目录作为包导入,然后lib/Types.py作为其中的子模块导入,创建模块对象lib并lib.Types在其中sys.modules.Types,它导入Types.py作为一个独立的模块,创建模块对象Types在sys.modules.所以,Types和lib.Types最终成为两个不同的模块对象.Python不会检查它们是否是同一个文件,以保持简单并避免再次猜测.
(这实际上是在Python的导入系统文章中将"粗心的陷阱"列为"双重导入陷阱".)
如果lib从中删除PYTHONPATH,则导入lib/foo.py将需要成为相对导入:
from .Types import Custom
Run Code Online (Sandbox Code Playgroud)
或绝对导入:
from lib.Types import Custom
Run Code Online (Sandbox Code Playgroud)
当在同一过程中通过两条不同的路径导入模块时(例如在此处使用import Typesin foo.py和import lib.Typesin)main.py,它实际上被导入了两次,产生了两个不同的模块对象,每个对象都有自己的不同函数和类实例(您可以自己使用进行检查id(obj_or_class)) ,有效突破is和isinstance测试。
这里的解决方案是在您的pythonpath中添加Project(而不是Project/lib)(无论如何,应该这样做-pythonpath / sys.path应该是包含软件包和模块的目录列表,而不是软件包目录本身),并from lib.Type import Custom在各处使用,因此您只有模块的一个实例。
| 归档时间: |
|
| 查看次数: |
2301 次 |
| 最近记录: |