gpt4 book ai didi

python - 动态加载类中的类标识 vs.通过导入加载的类

转载 作者:行者123 更新时间:2023-11-28 17:07:56 26 4
gpt4 key购买 nike

这是我正在处理的内容的最小复制。这是使用 Python 3.6.5:

示例.py:

import importlib.util
import inspect

from test import Test

t = Test()

spec = importlib.util.spec_from_file_location('test', './test.py')
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)

loaded_test = None
for name, obj in inspect.getmembers(module):
if inspect.isclass(obj):
loaded_test = obj

print(type(t))
print(loaded_test)
print(isinstance(t, loaded_test))
print(issubclass(t.__class__, loaded_test))

test.py(在同一目录):

class Test(object):
pass

运行此代码将为您提供以下输出:

<class 'test.Test'>
<class 'test.Test'>
False
False

那么,为什么我们使用 importlib 加载的对象(标识为“test.Test”)不是我使用 import 创建的“test.Test”类的实例或子类?有没有办法以编程方式检查它们是否属于同一类,或者是否不可能因为它们实例化的上下文不同?

最佳答案

Why is the object that we load using importlib, which is identified as test.Test, not an instance or subclass of the test.Test class I created using import?

类“只是”元类的一个实例。导入系统通常会阻止类对象被多次实例化:类通常是在模块范围内定义的,如果一个模块已经被导入,那么现有的模块只会被重复用于后续的导入语句。因此,对同一类的不同引用最终都指向位于同一内存位置的同一类对象。

通过使用 exec_module,您阻止了 sys.modules 中的“缓存命中”,强制再次执行类声明,并在中创建一个新的类对象内存。

issubclass 并没有像深入检查类源代码那样做任何聪明的事情,它或多或少只是在寻找身份(CPython 的实现 here ,具有精确匹配的快速 channel 和支持 ABCs 的一些并发症)

Is there a way to programmatically check if they're the same class, or is it impossible because the context of their instantiation is different?

他们不是同一个类(class)。尽管源代码相同,但它们存在于不同的内存位置。您不需要复杂的 exec_module 就能看到这一点,顺便说一句,有更简单的方法可以强制重新创建“相同”类:

>>> import test
>>> t = test.Test()
>>> isinstance(t, test.Test)
True
>>> del sys.modules['test']
>>> import test
>>> isinstance(t, test.Test)
False

或者,在函数 block 中定义类并从函数调用中返回它。或者,使用 type(name, bases, dict) 的三参数版本从相同的源代码创建类. isinstance 检查(CPython 实现 here )很简单,不会检测到这些误导。

关于python - 动态加载类中的类标识 vs.通过导入加载的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49838163/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com