1

一般情况:

  • 我不知道我将事先检查哪些模块,我不知道其中会包含什么:类、方法等。
  • 我确实知道我正在寻找什么课程,以及我需要用它做什么。例如,我需要运行一个特定的方法,cls.register
  • 我需要找到最有效的方法来做到这一点。

我什至没有得到具体的代码,或者我会发布它。但是我认为我有一些选择:

  1. 只需通过try/运行模块中的所有内容except
  2. if/else寻找我需要的方法
  3. 使用检查来查找模块中类的完全匹配
  4. 使用元类添加属性this_is_class_sought=True

1-3好像太粗略了,4好像太费劲了。

我的情况:

我试图将 Flask-Classy 与应用程序创建者/工厂集成。
我有一堆视图文件,我不知道这些文件中会有什么。我需要找到所有继承 FlaskView 的类,而不是 FlaskView 本身,然后运行类注册函数。

因此,例如来自dir(a_module)随机遇到的模块:

['FlaskView', 'AView', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'forms', 'models', 'redirect', 'render_template', 'request', 'url_for']

我需要确定它AView在那里,并运行注册方法。3,上面似乎有可能,但我还没有完全确定如何区分AView

做这个的最好方式是什么?

编辑:

我必须强调,重点是我不知道我将要查看哪些模块,或者它们将包含什么。我需要有效地提取我需要的信息并根据该信息采取行动。

编辑2:

__subclasses__() 大大简化了我的目的。

4

1 回答 1

0

听起来您正在尝试做一些骇人听闻的事情,但是...无论如何我都会提供帮助。如果选项 4 完全是一个选项,那么我建议您改用自注册元类/基类。

看看这个答案:Generic Python metaclass to keep track of subclasses

为完整性复制

def sublass_registry():
    ''' Create a metaclass to register subclasses '''

    class SublassRegistryMeta(type):
        def __init__(cls, name, bases, classdict):
            if classdict.get('__metaclass__') is SublassRegistryMeta:
                SublassRegistryMeta.lineage = [cls] # put root class at head of a list
            else:
                # sublclasses won't have __metaclass__ explicitly set to this class
                # we know they're subclassees because this ctor is being called for them
                SublassRegistryMeta.lineage.append(cls) # add subclass to list
            type.__init__(cls, name, bases, classdict)

    return SublassRegistryMeta

def subclasses(cls):
    ''' Return a list containing base and subclasses '''

    try:
        if cls.__metaclass__.lineage[0] is cls: # only valid for a root class
            return cls.__metaclass__.lineage
    except AttributeError:
        pass
    return None

class Car(object): # root class
    __metaclass__ = sublass_registry()

class Audi(Car): # inherits __metaclass__
    pass

class Ford(Car): # inherits __metaclass__
    pass

class Audi2(Audi): # sub-subclass also inherits __metaclass__
    pass

print subclasses(Car)
# [<class '__main__.Car'>, <class '__main__.Audi'>, <class '__main__.Ford'>, <class '__main__.Audi2'>]
print subclasses(Audi)
# None

issubclass或者,只需用一些循环遍历它就可以isinstance了。一般来说,你不需要任何尝试/除了这里,但为了安全起见,你可以添加一些。

于 2013-05-28T13:21:39.243 回答