将 Python Class 中的所有方法结果加载到字典

Load All Method Results in Python Class to Dictionary

如果我有一个像下面这样的class(实际上,它有更多的方法),我想将每个方法的结果加载到字典中,有没有更快的方法来做features_to_dict,如果我添加新方法,那也是模块化的?

from bs4 import BeautifulSoup

class CraigsPage():

    def __init__(self, page_file):
        self._page = open(page_file).read()
        self.soup = BeautifulSoup(self._page)
        self.title = self.soup.title.string
        self.body = str(self.soup.find('section', id='postingbody'))

    def get_title_char_count(self):
        return len(list(self.title.replace(' ', '')))

    def get_title_word_count(self):
        return len(self.title.split())

    def get_body_char_count(self):
        return len(list(self.body.replace(' ', '')))

    def features_to_dict(self):
        feature_dict = {}
        feature_dict['title_char_count'] = self.get_title_char_count()
        feature_dict['title_word_count'] = self.get_title_word_count()
        feature_dict['body_char_count'] = self.get_body_char_count()
        return feature_dict

Python classes 有 __dict__ 属性,它将 class 的所有属性存储为字典。以下代码段遍历 __dict__,试图找到以 get 开头的函数,并自动运行它们,将结果存储到字典中:

class A(object):
    def get_a(self):
        return 1

    def get_b(self):
        return 2

    def features_to_dict(self):
        self.d = {}
        for f_name, f in A.__dict__.iteritems():
            if 'get' in f_name:
                self.d[f_name[4:]] = f(self)
a = A()
a.features_to_dict()
print a.d

这个returns{'a': 1, 'b': 2}.

使用 dir() 方法代替 dict 属性。

class A(object):
    def method(self):
        return 123
    def call_all(self):
        skip = dir(object) + ['call_all']
        results = {}
        for key in dir(self):
            if key not in skip and callable(getattr(self, key)):
                try:
                    results[key] = getattr(self, key)()
                except Exception as e:
                    results[key] = e
        return results

inspect 模块对这类事情很方便:

def features_to_dict(self):
    members = inspect.getmembers(self, inspect.ismethod)
    return {name: method() for name, method in members if name.startswith('get')}

有点简单的方法,根本不使用内省并明确定义要调用的方法:

class A(object):
    methods_to_call = [
        "get_title_char_count",
        "get_title_word_count",
        "get_body_char_count",
    ]
    ...
    def features_to_dict(self):
        feature_dict = {}
        for method in self.methods_to_call:
            feature_dict[method[4:]] = getattr(self, method)()

        return feature_dict