首页 > 解决方案 > Python:如何将要处理的对象成员(可能嵌套更深)传递给函数?

问题描述

背景

我有一个包含列表成员 x 和 y 的对象字典:

plot_data._trace_d = {
    TraceType.A: {
        'abc': TraceData(x=[ 0, 1, 2, 3 ], y=[10, 11, 12, 13])
        'def': TraceData(x=[100, 101, 102, 103], y=[110, 111, 112, 113])
    },
    TraceType.B: {
        'abc': TraceData(x=[1000, 1001, 1002], y=['x', 'y', 'z']),
        'def': TraceData(x=[1010, 1011, 1012], y=['xx', 'yy', 'zz'])
    }
}

我需要将每条迹线展平以符合我的绘图工具(情节),以便我有以下形式的列表:

# TraceType.A
x = [0, 1, 2, 3, 100, 101, 102, 103]
y = [10, 11, 12, 13, 110, 111, 112, 113]
plot(x, y, ...)

# TraceType.B
x = [1000, 1001, 1002, 1010, 1011, 1012]
y = ['x', 'y', 'z', 'xx', 'yy', 'zz']
plot(x, y, ...)

我目前的解决方案

用字符串传递要压平的成员。

class TraceData:
    def __init__(self, x, y):
        x = []
        y = []
    # ...

class PlotData:
    def __init__(self):
        self._trace_d = {
            TraceType.A: TraceData(),
            TraceType.B: TraceData(),
        }
    # ...
    def flatten_trace_data(self, trace_type, dimension): # HERE! dimension is a string
        """For a trace type, get the lists for all nodes and concatenate them
        into a single list. Useful to build a single Plotly trace for multiple
        nodes."""
        flat_list = []
        for node, td in self._trace_d[trace_type].items():
            print("Flattening node %r dim %s" % (node, dimension))
            flat_list += getattr(td, dimension)

        return flat_list

plot_data = PlotData()
# ...
x = plot_data.flatten_trace_data(TraceType.A, 'x')

我想要的是

把维度参数给成字符串感觉很脏,感觉matlaby。有没有办法告诉成员函数对成员的给定参数执行某些操作?像这样的东西:

x = plot_data.flatten_trace_data(TraceType.A, TraceData.x)

我试过这个,因为为什么不,但TraceData没有属性'x'

什么是一种优雅的方法来告诉展平函数要展平对象的哪个维度(在嵌套的嵌套字典中)?

标签: pythonmember

解决方案


用 getattrib 试试这样的东西。


def flatten_trace_data(self, trace_type, dimension):
"""For a trace type, get the lists for all nodes and concatenate them into a single list. Useful to build a single Plotly trace for multiple nodes."""
    flat_list = [] 
    for node, l in self._trace_d[trace_type].items():
        print("Flattening node %r dim %s" % (node, dimension))
        flat_list += getattr(l, dimension)
    return flat_list

编辑1,使用属性

class PlotData: 
    def __init__(self): 
        self._trace_d = { 
           TraceType.A: TraceData(), 
           TraceType.B: TraceData(), } # ... 

    @property
    def x_A(self):
        flat_list = [] 
     for node, td in self._trace_d[TraceType.A].items():
         flat_list += td.x
      return flat_list

编辑 2

你想要实现的是这样的。

plot_data = PlotData()
x = plot_data.A.x
y = plot_data.A.y

这将是更pythonic的方式。

为此,您需要重新考虑 TaceData、TraceType 和 PlotData 中的每个类。


推荐阅读