python – 确定对象是否为Foo类型而不导入类型Foo

假设我在文件中定义了一个类:

import stuff
import more stuff
import stuff that takes a long time to import
class Foo(object):
    def __init__(self, arg1, arg2 etc.):
        self.arg1 = arg1 
        self.arg2 = arg2
        # Lots of other stuff
    # Lots of methods

在另一个文件中我有这个代码:

from big_file import Foo
def do_stuff(obj):
    if isinstance(obj, Foo):
        do_stuff
    else:
        do_other_stuff

假设文件Foo需要很长时间才能导入,原因是我无法控制.如何重构此代码以不导入Foo但仍可靠地检查类型?我不认为鸭子打字适合我的特殊情况.

我应该…检查obj基础的字符串表示?还是有另一种更规范的方式?

最佳答案 通常情况下,这不是问题.如果您有big_file.Foo的实例,那么即使未从其他文件显式引用,其父模块也已在之前导入. Python模块仅在第一次导入时加载一次(前提是您没有进行任何显式重新加载或使用sys.modules搞乱).由于它已经被导入,因此在其他文件中执行导入big_file应该立即运行.

但是,如果你的其他文件在某些​​情况下只会遇到big_file.Foo而big_file只在实际需要的时候导入其他地方,那么你可以检查对象的类(这不支持子类):

def do_stuff(obj):
    if (obj.__class__.__module__, obj.__class__.__name__) == ('big_file', 'Foo'):
        do_stuff
    else:
        do_other_stuff

由于您已指出可以在应用程序中的任何位置导入big_file.Foo并且您希望支持子类,因此您可以检查其模块是否已导入并有条件地检查类型.

import sys

def is_Foo(obj):
    if 'big_file' in sys.modules:
        return isinstance(obj, sys.modules['big_file'].Foo)
    else:
        return False

def do_stuff(obj):
    if is_Foo(obj):
        do_stuff
    else:
        do_other_stuff
点赞