Python:如何将要处理的对象成员(可能嵌套更深)传递给函数?
Posted
技术标签:
【中文标题】Python:如何将要处理的对象成员(可能嵌套更深)传递给函数?【英文标题】:Python: how to pass to a function which object member (possibly nested deeper down) to work on? 【发布时间】:2020-02-23 12:30:25 【问题描述】:背景
我有一个包含列表成员 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'
。
什么是告诉展平函数要展平的对象的哪个维度(在嵌套的嵌套字典中)的优雅方法?
【问题讨论】:
使用getattr
setattr
?
@juanpa.arrivillaga 它仍然使用字符串,但绝对是一个很好的改进。我将更新代码以使用它。
【参考方案1】:
用 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 中的每个类。
【讨论】:
有趣的是,在@juanpa.arrivillaga 发表评论后,我刚刚通过此更改编辑了我的问题。但是flatten_trace_data
的参数仍然是一个字符串,我不确定它是否非常pythonese。
@Gauthier 是的,很有趣。据我所知,是的,它是 pytonic 因为这是使用函数执行此操作的唯一方法。但是,您可以在 PlotData 类中创建属性来获取字符串。我会更新我的awser。
如果它是pythonic,那么它就是......我刚刚看到getattr
无论如何都需要一个字符串。注意:您的答案第一行的错字,getattrib
似乎不存在。
使用属性强制我创建 n(TraceType) * n(dimensions) 函数?
@Gauthier 是的,完全正确。这不是很合适,但是您可以想象创建一个 TraceD 类。以上是关于Python:如何将要处理的对象成员(可能嵌套更深)传递给函数?的主要内容,如果未能解决你的问题,请参考以下文章