Python:查找所有具有特定属性的 类

Python: finding all classes with a particular attribute

我看到了几乎相同的 C# post,但找不到任何与 Python 相关的内容。

因为我刚开始学习Python,我有一种感觉,我会想起我以前用过的一个属性,比如.count(),而忘记哪些对象有这个属性。

我想编写一个函数,给定目录列表和某个属性,return 一组具有该属性的对象 类。 (理想情况下,我可以搜索在此函数 运行 时导入的所有 类 对象,而不仅仅是 dir() 中的内容)

这是我目前的情况:

    def whereattr(directory_list, attrib):
        haveit = set()
        for obj in directory_list:
            try:
                haveit.add(type(eval(obj)) if hasattr(eval(obj), attrib) else '')
            except:
                pass
        return haveit

我正在使用 try/except,因为我发现我无法评估所有对象。

示例:

    In [244]: whos
    Variable       Type         Data/Info
    -------------------------------------
    DataFrame      type         <class 'pandas.core.frame.DataFrame'>
    Series         type         <class 'pandas.core.series.Series'>
    count          int          5
    counts         dict         n=97
    first_letter   function     <function <lambda> at 0x1039daf50>
    frame          DataFrame          _heartbeat_        <...>n[3560 rows x 18 columns]
    get_counts     function     <function get_counts at 0x10770ac08>
    haveit         list         n=0
    itertools      module       <module 'itertools' from <...>ib-dynload/itertools.so'>
    json           module       <module 'json' from '/Use<...>on2.7/json/__init__.pyc'>
    letter         str          A
    line           str          { "a": "Mozilla\/4.0 (com<...>.935799, -77.162102 ] }\n
    names          _grouper     <itertools._grouper object at 0x103b51b90>
    path           str          pydata-book/ch02/usagov_b<...>2012-03-16-1331923249.txt
    rec            dict         n=16
    records        list         n=3560
    results        Series       0                Mozilla/<...>ngth: 3440, dtype: object
    test           set          set([])
    testfun        function     <function testfun at 0x107b2d938>
    tz             unicode      Asia/Seoul
    tzs            list         n=3440
    vkp            list         n=97
    whereattr      function     <function whereattr at 0x107b2d9b0>
    x              unicode      Mozilla/4.0 (compatible; <...>T4.0E; .NET CLR 1.1.4322)

    In [247]: whereattr(dir(), "count")
    Out[247]: {'', str}

有人能告诉我我做错了什么吗?很明显,list、Series等都有count属性,应该包括在内。

此外,如果你想因为我的代码的任何其他问题而责备我,我愿意接受(很好的)批评。

您不应该使用 eval() 来查找对象。尝试这样的事情:

def whereattr(directory_list, attrib):
    haveit = set()
    scope = globals()
    for obj_name in directory_list:
        if obj_name in scope:
            obj = scope[obj_name]
            if hasattr(obj, attrib):
                haveit.add(type(obj))
    return haveit

这将在全局范围内找到具有给定属性的所有对象。

编辑: 尽管使用 eval() 是不好的做法,但您的原始代码应该有效。所以我实际上不确定潜在的问题是什么。 (请参阅我对原始问题的评论。)

您应该将 except 子句更改为 except Exception, e: print str(e)。它告诉你你做错了什么。如果您丢失 eval,它似乎可以工作。

def whereattr(directory_list, attrib):
        haveit = set()
        for obj in directory_list:
            try:
                haveit.add(type(obj) if hasattr(obj, attrib) else '')
            except Exception, e:
                print str(e)
        return haveit 

>>> whereattr([list], "count")
set([<type 'type'>])
>>> 

dir 在这里有点没用,我宁愿推荐 localsglobals,因为它给了你参考,所以你不需要使用 eval。

[label for label, ref in locals().items() if hasattr(ref, 'count')]

显然你可以把它放到像

这样的函数中
whereattr = lambda scope, attr: [label for label, ref in scope.items() if hasattr(ref, attr)]

然后你这样使用它

whereattr(locals(), 'count')

whereattr(vars(__builtin__), 'count')