【问题标题】:How to reference function defined in __init__ super class如何引用 __init__ 超类中定义的函数
【发布时间】:2020-08-24 07:49:35
【问题描述】:

我的 __init__ 类中有一个辅助函数 (def convert(dictionary) 来帮助进行配置设置。定义如下:

class Configuration:

    def __init__(self, config_file=None, config=None):

        if config_file is not None:
            with open(config_file) as in_file:
                self._config = yaml.load(in_file, Loader=yaml.FullLoader)
        elif config is not None:
            self._config = config
        else:
            raise ValueError("Could not create configuration. Must pass either location of config file or valid "
                             "config.")

        def convert(dictionary):
            return namedtuple('Config', dictionary.keys())(**dictionary)

这使我可以在__init__ 内拨打电话,如下所示:

        self.input = convert(self._config["input"])
        self.output = convert(self._config["output"])
        self.build = convert(self._config["build_catalog"])

由于我要设置多个配置,因此我想从他的类继承如下:

class BuildConfiguration(Configuration):

    def __init__(self, config_file=None, config=None):

        super().__init__(config_file, config)

        self.input = convert(self._config["input"])
        self.output = convert(self._config["output"])
        self.build = convert(self._config["build_catalog"])

但是,我无法从父类访问convert。我也试过这个:

self.input = super().__init__.convert(self._config["input"])

这似乎也行不通。

所以问题是我如何从子类访问super().__init__ 中定义的函数?

【问题讨论】:

  • tl;博士; 你不能。如果您想访问它,请在 __init__ 之外定义它们,方法是在模块命名空间中创建一个方法或 gloably,这样嵌套函数绝不是一件好事(除非您真的必须这样做)。由于convert 函数与Configuration 类没有任何关系,只需将其设置为module 中的普通function 即可
  • 从逻辑上讲,def convert只在调用__init__时创建,只存在于其作用域内,__init__结束时被丢弃。所以不,它不存在于它之外。
  • 另外,您在函数的每次调用上创建另一个namedtuple 类。整个设置很糟糕。在外部定义 namedtuple 类,因此您只需创建 其中一个 并在全局范围内或可能作为方法定义该辅助函数。
  • @juanpa.arrivillaga 当然,如果你要退货,没关系。嘿,这就是我们为decorators 所做的事情。但是在这种情况下,这没有任何意义,是的

标签: python inheritance init


【解决方案1】:

你不能。每次调用 __init__ 时都会创建一个新函数并被丢弃,它在函数之外不存在。请注意,这也适用于由namedtuple('Config', dictionary.keys())(**dictionary) 创建的类。继续创建所有这些不必要的类确实不好,这完全违背了namedtuple 的目的,即创建内存高效的记录类型。在这里,每个实例都有自己的类!

你应该如何定义它:

Config = namedtuple('Config', "foo bar baz")

def convert(dictionary): # is this really necessary?
    return Config(**dictionary) 

class Configuration:

    def __init__(self, config_file=None, config=None):

        if config_file is not None:
            with open(config_file) as in_file:
                self._config = yaml.load(in_file, Loader=yaml.FullLoader)
        elif config is not None:
            self._config = config
        else:
            raise ValueError("Could not create configuration. Must pass either location of config file or valid "
                             "config.")

        self.input = convert(self._config["input"])
        self.output = convert(self._config["output"])
        self.build = convert(self._config["build_catalog"])

虽然在这一点上,使用起来似乎更干净

Config(**self._config["input"])

等等,然后放弃助手convert

【讨论】:

  • 是的,对最后一种方法很满意。谢谢。
猜你喜欢
  • 1970-01-01
  • 2014-03-20
  • 2021-01-17
  • 1970-01-01
  • 1970-01-01
  • 2017-09-07
  • 2021-02-22
  • 2010-10-09
  • 1970-01-01
相关资源
最近更新 更多