我想直接调用dict
的每个元素的属性而不进行迭代。我用matplotlib
做了一个小例子,其中应创建多个数字并同时调用:
import matplotlib.pyplot as plt
class Graph(object):
def __init__(self):
self.figures = dict()
self.axes = dict()
for i in [1, 2]:
self.figures[i], self.axes[i] = plt.subplots()
def ax(self):
return self.axes
def fig(self):
return self.figures
graphic = Graph()
graphic.ax().plot([0,1,2],[5,3,1])
graphic.fig().show()
因此应该调用graphic.ax()
/ graphic.fig()
中的每个轴/数字。有可能采取直接方法吗?
答案 0 :(得分:2)
如何从列表的所有元素调用方法(这里的字典似乎没用)这个问题显示了Is there a way to run a method for all instances of a class in python?
我们可以将它调整到matplotlib案例,如下所示。这允许例如调用graphic.axes.plot([0,1,2],[5,3,1])
以将此数据绘制到所有存储的轴。
import matplotlib.pyplot as plt
class CallableContainer(object):
def __init__(self):
self.values = []
def append(self,x):
self.values.append(x)
def __getattr__(self, key):
def fn(*args,**kwargs):
return [getattr(x,key)(*args,**kwargs) for x in self.values]
return fn
class Graph(object):
def __init__(self):
self.figures = CallableContainer()
self.axes = CallableContainer()
for i in [1, 2]:
fig,ax = plt.subplots()
self.figures.append(fig)
self.axes.append(ax)
graphic = Graph()
graphic.axes.plot([0,1,2],[5,3,1])
graphic.figures.tight_layout()
plt.show()
然而,如果真正的问题是如何制作不同的样式图,那么我们宁愿编写一个函数,它会生成一个图形并用所有需要的样式调用它,如下所示:
import matplotlib.pyplot as plt
def create_graph():
fig, ax = plt.subplots()
ax.plot([1,2,4])
ax.scatter([1,2,3],[3,3,3])
styles = ["grayscale", "Solarize_Light2", "ggplot"]
for style in styles:
with plt.style.context((style)):
create_graph()
plt.show()
这会使用不同的样式创建相同图形的三倍。
答案 1 :(得分:1)
我仍然认为迭代图形和/或轴实例是可行的方法。如果您想要比实现课程中所需的每个功能更通用,那么您可以使用getattr
函数。像这样:
import matplotlib.pyplot as plt
class Graph(object):
def __init__(self):
self.figures = dict()
self.axes = dict()
for i in [1, 2]:
self.figures[i], self.axes[i] = plt.subplots()
def ax(self):
return self.axes
def fig(self):
return self.figures
def call_ax_method(self, method, *args, **kwargs):
for ax in self.axes.values():
func = getattr(ax,method)
func(*args, **kwargs)
def call_fig_method(self, method, *args, **kwargs):
for fig in self.figures.values():
func = getattr(fig, method)
func(*args,**kwargs)
graphic = Graph()
graphic.call_ax_method('plot',[0,1,2],[5,3,1], lw = 2, ls='-', marker='o')
graphic.call_fig_method('tight_layout')
plt.show()
顺便说一句,您并不真正需要类中的ax
和fig
方法,因为您可以直接访问这些属性。
如果您不想调用您的功能,请拨打call_ax_method'和' call_fig_method',您可以编写第二个派生自dict
的类,并为其实现__call__
方法:
import matplotlib.pyplot as plt
class InstanceDict(dict):
def __init__(self, *args, **kwargs):
super().__init__(*args,**kwargs)
def __call__(self, method, *args, **kwargs):
for inst in self.values():
func = getattr(inst, method)
func(*args, **kwargs)
class Graph(object):
def __init__(self):
self.figures = InstanceDict()
self.axes = InstanceDict()
for i in [1, 2]:
self.figures[i], self.axes[i] = plt.subplots()
graphic = Graph()
graphic.axes('plot',[0,1,2],[5,3,1], lw = 2, ls='-', marker='o')
graphic.figures('tight_layout')
plt.show()