from cppy.cp_util import *

# 装饰器改写类
# - 找到以f_开头的方法
# - 将方法函数的返回值赋值给对象的data属性
# - 返回对象自身 
def return_self_decorator(cls):
    def return_self(func):
        # 定义一个闭包函数，用于接收参数
        def wrapper(self, *args, **kwargs):            
            self.data = func(self, *args, **kwargs)            
            return self # 返回类自身        
        return wrapper
    
    for name, method in cls.__dict__.items():
        # 判断属性是否可调用，且属性名以f_开头
        if callable(method) and name.startswith('f_'):            
            # 为类改写属性，将封装后的函数赋值
            setattr(cls, name, return_self(method))    
    return cls

@return_self_decorator
class Flow():        
    def test(self):
        return 'test'
    
    def f_extract_file_words(self, filepath):
        return extract_file_words(filepath)        
    
    def f_get_frequencies(self):
        return get_frequencies(self.data)        
    
    def f_sort_dict(self):
        return sort_dict(self.data)        

    def f_print_word_freqs(self, n):
        print_word_freqs(self.data, n)        


# 顺序调用
Flow().f_extract_file_words(testfilepath).f_get_frequencies().f_sort_dict().f_print_word_freqs(10)

'''
改写后，参与 function flow 功能的方法 
 - 需要以 'f_' 开头
 - 类方法默认不写第一个参数，数据都在 .data 里面

仍旧需要特殊的方法写法
所以，还是 1，2种方法比较自然
'''