Вопрос

Following the SO questions What is a clean, pythonic way to have multiple constructors in Python? and Can you list the keyword arguments a Python function receives? I want to create a base class that has a from_yaml classmethod, and which also removes unneeded keyword args as shown below. But I think I need to reference the derived class's __init__ method from the base class. How do I do this in Python?

def get_valid_kwargs(func, args_dict):
    valid_args = func.func_code.co_varnames[:func.func_code.co_argcount]
    kwargs_len = len(func.func_defaults)  # number of keyword arguments
    valid_kwargs = valid_args[-kwargs_len:]  # because kwargs are last
    return dict((key, value) for key, value in args_dict.iteritems()
                if key in valid_kwargs)


class YamlConstructableClass(object):
    @classmethod
    def from_yaml(cls, yaml_filename):
        file_handle = open(yaml_filename, "r")
        config_dict = yaml.load(file_handle)
        valid_kwargs = get_valid_kwargs(AnyDerivedClass.__init__, config_dict)  # I don't know the right way to do this
        return cls(**valid_kwargs)


class MyDerivedClass(YamlConstructableClass):
    def __init__(self, some_arg, other_arg):
        do_stuff(some_arg)
        self.other_arg = other_arg

derived_class = MyDerivedClass.from_yaml("my_yaml_file.yaml")
Это было полезно?

Решение

You already have a reference to the correct class: cls:

valid_kwargs = get_valid_kwargs(cls.__init__, config_dict)

The class method is bound to the class object it is being called on. For MyDerivedClass.from_yaml(), cls is not bound to parent class but to MyDerivedClass itself.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top