扩展Python中父类方法的功能

时间:2018-08-08 12:23:54

标签: python inheritance methods decorator

我有一个模板词典,该词典通过行和列索引(row_idcol_id)告诉我在2D列表中可以找到某些变量的位置。但是,某些变量的行索引可以是动态的,因此我使用lambda表达式根据一些输入来计算这些索引。模板的简化版本:

ROW_ID = "row_id"
COL_ID = "col_id"
VALUE = "value"
VARIABLES = "variables"

template = {
    "record_1": {
        ROW_ID: 0,
        VALUE: None,
        VARIABLES: {
            "var1": {
                COL_ID: 0,
                VALUE: None},
            "var2": {
                COL_ID: 1,
                VALUE: None}}},

    "record_2": {
        ROW_ID: lambda row_id, **kw: do_something,
        VALUE: None,
        VARIABLES: {
            "var3": {
                COL_ID: 0,
                VALUE: None}}}}

我有一个带有方法(eval_template())的基类,该方法遍历此嵌套字典,记住最后的行和列索引并评估lambda表达式:

import copy

class baseClass(object):

    def __init__(self):
        self.template = copy.deepcopy(template)

    def eval_template(self):
        row_id = None

        def inner(node=None):
            nonlocal row_id
            col_id = None

            if node is None:
                node = self.template

            for key, value in node.items():
                if callable(value):
                    value = value(row_id=row_id)
                    node[key] = value

                elif isinstance(value, dict):
                    inner(value)

                if key is ROW_ID:
                    row_id = value 
                elif key is COL_ID:
                    col_id = value

        inner()

这一切都很好,但是现在我想从baseClass创建一个子类并扩展eval_template()的功能。子类将具有方法(get_values()),该方法可以使用列和行索引(template从2D列表中获取row_id中变量(或整个行)的值, col_id)并将其添加到字典中(请参见下面的--->)

class childClass(baseClass):

    def __init__(self, 2d_list):
        super().__init__()
        self.2d_list = 2d_list

    def get_values(self, row_id, col_id):
        if col_id is None:
            return self.2d_list[row_id]
        else:
            return self.2d_list[row_id][col_id]

        def eval_template(self):
            row_id = None

            def inner(node=None):
                nonlocal row_id
                col_id = None

                if node is None:
                    node = self.template

                for key, value in node.items():
                    if callable(value):
                        value = value(row_id=row_id)
                        node[key] = value

                    elif isinstance(value, dict):
                        inner(value)

                    if key is ROW_ID:
                        row_id = value 
                    elif key is COL_ID:
                        col_id = value
    ---->           elif key is VALUE:
                        node[key] = self.get_values(row_id, col_id)

            inner()

我的问题是我如何才能在baseClass中扩展原始eval_template()而不复制整个方法并添加两个新行,就像我在上面的示例中所做的那样。有没有办法装饰这个内部功能,还是有一个更优雅的解决方案?

0 个答案:

没有答案