繁体   English   中英

地块层次结构中的Python错误:TypeError:无法散列的类型:'list'

[英]Python error in plots hierarchy : TypeError: unhashable type: 'list'

我正在为我的样式图开发产品的类层次结构,这对于我的目的很有用,

当我尝试从子类实例化绘图时,我收到了标题为TypeError: unhashable type: 'list'的错误报告,为了简化错误,我简化了该类,但是可以使用和测试这些类,尤其是仅当我尝试从子类调用时,才收到此错误,在我未获得的顶级调用中,现在生成了图,现在让我报告几个类:

层次结构以抽象类开始:

from abc import ABCMeta, abstractmethod
import matplotlib.pyplot as plt
import numpy as np
from abc import ABCMeta, abstractmethod
from cycler import cycler

class BasePlot(metaclass=ABCMeta):

   def __init__(self, title : str = ' ' , filename : str = ' '):
      self.title = title
      self.filename = filename   

   def schemes(self, style:str = 'nb'):
         color = {} 
         color['nb']   = ['#8DA0CB', '#E58AC3', '#A6D853', '#FFD930', '#B2B2B2', '#5FC3A4', '#FC8D62', '#66C2A5']
         return color[style]

   def linestyles(self, style : str = 'ls1'):  
         linestyles = {}
         linestyles['paper'] = [(0, ()), (0, (3, 1, 1, 1, 1, 1)), (0, (5, 5)),(0, (5, 1)),(0, (3, 5, 1, 5)),(0, (3, 5, 1, 5, 1, 5)),(0, (1, 1)),(0, (5, 10)) ]
         return linestyles[style]                                                                                                   

   @abstractmethod
   def style(self,*args,**kwargs):
      pass

从这个基类继承了一个几乎定义了我需要的所有东西的类,它被命名为产生默认图的默认类!

 class DefaultPlot(BasePlot) :

    def __init__(self, figsize,*args,**kwargs):
        self.var = [*args]
        self.params = kwargs
    def style(self,*args):
        self.variable = [*args]
    def cycle(self,n : str):
            if n == '0':
                  return plt.cycler("color", self.parameters['scheme'])      #colors)         
            elif n=='1':
                  return plt.cycler("color", self.parameters['scheme']) + plt.cycler("linestyles", self.parameters['linestyles'])
    def setparams(self, kwargs):
             self.parameters = kwargs
             if 'scheme' in self.parameters.keys():
                 v = self.parameters['scheme']  
                 self.parameters['scheme'] = self.schemes(v)

             if 'font' not in self.parameters.keys():
                self.parameters['font'] = 'serif'
             if 'scheme' not in self.parameters.keys():
                self.parameters['scheme'] = self.schemes('nb')
             if 'cycle' not in self.parameters.keys():
                self.parameters['cycle']  = self.cycle('0')
             if 'linestyles' not in self.parameters.keys():
                self.parameters['linestyles'] = self.linestyles('paper')


             myparams = {
               'axes.prop_cycle': self.parameters['cycle'],     
               'grid.color' : 'gray',
               'font.family': self.parameters['font'] ,
               'font.style' : 'italic'
             }

             plt.rcParams.update(myparams)

    def __call__ (self,nrows,ncols,*args,**kwargs):

       self.style(*args)
       self.setparams(kwargs)

       if nrows == ncols ==1:
            self.fig, self.axs = plt.subplots(nrows,ncols,figsize=(9.5,4.5))
       else:
            self.fig, self.axs = plt.subplots(nrows,ncols,figsize=(12,6))
       for i in range(nrows):
          for j in range(ncols):
             if nrows == ncols == 1:
                 self.axs.set_title('', color='#555555')
                 legend = leg = self.axs.legend()

             else:
                 self.axs[i,j].set_title('', color='#555555')
                 legend = leg = self.axs[i,j].legend()
             legend.get_frame().set_linewidth(1.2)
             plt.setp(legend.get_texts(), color='#555555')

             if nrows == ncols ==1 :
                plt.subplots_adjust(left=0.125 , bottom=0.125, right=0.95, top=0.87, wspace=0, hspace=0)
             else:   
                plt.subplots_adjust(left=0.06 , bottom=0.1, right=0.95, top=0.95, wspace=0.2, hspace=0.4)
       return self.fig,self.axs

最后,我继承了最后一个级别的类,该类的目的(即使在这里看起来也不是)是替换上面的默认类中定义的参数,以便创建这样的几个类来生成样式图(基本上在这个类中我替换了颜色..字体的刻度等)

class Standard(DefaultPlot):

def __init__(self , figsize , *args , **kwargs):
    self.args = [*args]
    self.params = kwargs
    super().__init__(figsize,*self.args, **self.params )

def setparams(self, kwargs):

         self.parameters = kwargs
         if 'scheme' in self.parameters.keys():
              v = self.parameters['scheme']  
              self.parameters['scheme'] = self.schemes(v)
         if 'linestyles' not in self.parameters.keys():
            self.parameters['linestyles'] = self.linestyles('paper')
         if 'scheme' not in self.parameters.keys():
            self.parameters['scheme'] = self.schemes('nb')
         if 'cycle' not in self.parameters.keys():
            self.parameters['cycle']  = self.cycle('0')

         super().setparams(self.parameters)

从主脚本调用该类:

import numpy as np
import matplotlib.pyplot as plt
#import defaultplot 
import qualityplot

def main():

    x = np.linspace(0,2*np.pi,50)
    y = np.sin(x)

    fig,axs = qualityplot.Standard(figsize=(9.5,4.5))(1,1,**{'scheme':'nb'})
    #fig,axs = defaultplot.DefaultPlot(figsize=(9.5,4.5))(1,1,**{'scheme':'nb'})

    axs.plot(x,y)
    plt.show()

现在,如果您尝试运行并调用qualityplot,则会收到以下错误消息: TypeError: unhashable type: 'list'但是如果您调用顶级defaultpolot.DefaultPlot(最后一条注释行),一切就正常了! 我不知道我错了! 我该如何修理?

该错误告诉您不能将列表用作字典键。 即以下是不可能在python中

a = {[1,2,3] : "A"}

在您的代码中会发生此问题,因为您更改了self.parameters['scheme']的类型。 它可能首先是字符串,然后在以下代码中转到列表。

     self.parameters = kwargs
     if 'scheme' in self.parameters.keys():
          v = self.parameters['scheme']  
          self.parameters['scheme'] = self.schemes(v)

现在,这是super方法中的第二次调用,其中self.parameters['scheme']已经是列表。 在这种情况下, self.schemes(list)无效,将导致错误。

schemes函数中,将color ['nb']设置为列表。

Standard.setparams函数中,将此列表放入self.parameters['scheme']然后调用DefaultPlot.setparams

DefaultPlot.setparams ,调用v等于此列表的BasePlot.schemes(v)

BasePlot.schemes您调用的return color[style]的样式等于此列表的样式,该样式不起作用(样式应为字符串)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM