Python: Iterating through constructor's arguments

前端 未结 9 2074
囚心锁ツ
囚心锁ツ 2021-02-05 15:07

I often find myself writing class constructors like this:

class foo:
    def __init__(self, arg1, arg2, arg3):
        self.arg1 = arg1
        self.arg2 = arg2
         


        
9条回答
  •  栀梦
    栀梦 (楼主)
    2021-02-05 15:44

    Provided answers rely on *vargs and **kargs arguments, which might not be convenient at all if you want to restrict to a specific set of arguments with specific names: you'll have to do all the checking by hand.

    Here's a decorator that stores the provided arguments of a method in its bound instance as attributes with their respective names.

    import inspect
    import functools
    
    def store_args(method):
        """Stores provided method args as instance attributes."""
        argspec = inspect.getargspec(method)
        defaults = dict(zip( argspec.args[-len(argspec.defaults):], argspec.defaults ))
        arg_names = argspec.args[1:]
        @functools.wraps(method)
        def wrapper(*positional_args, **keyword_args):
            self = positional_args[0]
            # Get default arg values
            args = defaults.copy()
            # Add provided arg values
            list(map( args.update, ( zip(arg_names, positional_args[1:]), keyword_args.items() ) ))
            # Store values in instance as attributes
            self.__dict__.update(args)
            return method(*positional_args, **keyword_args)
    
        return wrapper
    

    You can then use it like this:

    class A:
        @store_args
        def __init__(self, a, b, c=3, d=4, e=5):
            pass
    
    a = A(1,2)
    print(a.a, a.b, a.c, a.d, a.e)
    

    Result will be 1 2 3 4 5 on Python3.x or (1, 2, 3, 4, 5) on Python2.x

提交回复
热议问题