【问题标题】:How to access keyword argument default values of inherited class如何访问继承类的关键字参数默认值
【发布时间】:2018-10-16 15:41:11
【问题描述】:

我正在尝试对seaborn.JointGrid 类进行一些修改。我的计划是创建一个子类并从JointGrid 类继承大多数方法,如下所示:

import seaborn

class CustomJointGrid(seaborn.JointGrid):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

如果我这样做,我将无法访问变量sizeratiospace 等,它们是__init__ method of JointGrid 的一部分:

def __init__(self, x, y, data=None, size=6, ratio=5, space=.2,
dropna=True, xlim=None, ylim=None) 

我注意到这些变量没有在JointGrid 类中使用__init__ 方法中的通常self.size = size 进行初始化。也许这就是为什么我无法从我的子班访问它们的原因?

如何访问这些变量sizeratiospace 等?

【问题讨论】:

  • 这些值在argskwargs 中。见:stackoverflow.com/questions/3394835/args-and-kwargs
  • @StephenRauch 这是真的吗?当我执行print(kwargs.items())print(*args) 时,它只显示我调用CustomJointGrid 的参数,而不是我没有传递的“默认”参数。所以如果我说CustomJointGrid("x data", "y data", data=data),变量size是不可用的。
  • 默认参数在您继承的源中。不确定我是否理解症结所在。
  • @StephenRauch 但是我如何访问它们?例如,如果我想在我的自定义子类中将 f = plt.figure(figsize=(size, size)) 更改为类似的内容:f = plt.figure(figsize=(size, 2 * size)) 它会显示 AttributeError: 'CustomJointGrid' object has no attribute 'size'
  • @StephenRauch 不确定我是否理解。您的意思是将size 添加到super().init(size=5, *args, **kwargs)

标签: python arguments subclass seaborn default-value


【解决方案1】:

您可以使用inspect.getfullargspec 来执行此操作:

>>> import seaborn, inspect
>>> spec = inspect.getfullargspec(seaborn.JointGrid.__init__)
>>> defaults = spec.kwonlydefaults or {}
>>> defaults.update(zip(spec.args[-len(spec.defaults):], spec.defaults))
>>> defaults
{'data': None, 'size': 6, 'ratio': 5, 'space': 0.2, 'dropna': True, 'xlim': None, 'ylim': None}

请注意,您的代码只需执行一次,因为导入的类的签名不会改变。

【讨论】:

  • 谢谢。这就是我要找的!
【解决方案2】:

为什么不直接使用与要子类化的类相同的参数?

import seaborn

class CustomJointGrid(seaborn.JointGrid):

    def __init__(self, x, y, data=None, size=6, ratio=5, space=.2,
                 dropna=True, xlim=None, ylim=None, **kwargs):
        super().__init__(x, y, data=data, size=size, ratio=ratio, space=space,
                         dropna=dropna, xlim=xlim, ylim=ylim)

否则你可以自己设置一些默认值,

class CustomJointGrid(seaborn.JointGrid):

    def __init__(self, *args, **kwargs):
        size = kwargs.get("size", 6)
        kwargs.update(size=size)
        super().__init__(*args, **kwargs)
        # use size here
        self.someattribute = size*100

【讨论】:

  • 我认为从父类继承它们会更好更容易吗?
  • 视情况而定。我不知道你最终想要达到什么目标。但我用不同的选项更新了答案。
  • 谢谢。我想使用与父类中定义的相同的size、`ratio` 等。第二个答案的问题是size的默认选项(6)如果不可用(size不在kwargs中),因此它设置size=10
  • 在那种情况下,我想我不明白这个问题。我想你想改变大小?但您当然也可以将其设置为 6
  • 你不能改变父类的那一行。要么重写完整的__init__ 方法并在那里使用自定义行,要么按原样初始化FacetGrid,然后执行self.fig.set_size_inches( ... ) 之类的操作。知道图的大小是size,就可以做w,h=self.fig.get_size_inches(); fig.set_size_inches(w, 2*h)这样的事情了。
猜你喜欢
  • 2011-04-18
  • 1970-01-01
  • 2021-05-08
  • 2011-01-09
  • 1970-01-01
  • 1970-01-01
  • 2011-06-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多