Python: Iterating through constructor's arguments

前端 未结 9 1859
囚心锁ツ
囚心锁ツ 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:55

    You can do that both for positional and for keyword arguments:

    class Foo(object):
        def __init__(self, *args, **kwargs):
            for arg in args:
                print arg
            for kwarg in kwargs:
                print kwarg
    

    * packs positional arguments into a tuple and ** keyword arguments into a dictionary:

    foo = Foo(1, 2, 3, a=4, b=5, c=6) // args = (1, 2, 3), kwargs = {'a' : 4, ...}
    
    0 讨论(0)
  • 2021-02-05 15:55

    As others have noted, you should probably stick to your original 'pythonic' method in most cases.

    However, if you really want to go the whole nine yards, here's some code that neatly deals with args, keyword args if desired, and avoids boilerplate repetition:

    def convert_all_args_to_attribs(self, class_locals):
        class_locals.pop('self')
        if 'kwargs' in class_locals:
            vars(self).update(class_locals.pop('kwargs'))
        vars(self).update(class_locals)
    
    class FooCls:
        def __init__(self, foo, bar):
            convert_all_args_to_attribs(self, locals())
    
    class FooClsWithKeywords:
        def __init__(self, foo, bar, **kwargs):
            convert_all_args_to_attribs(self, locals())
    
    f1 = FooCls(1,2)
    f2 = FooClsWithKeywords(3,4, cheese='stilton')
    
    
    print vars(f1) #{'foo': 1, 'bar': 2}
    print vars(f2) #{'cheese': 'stilton', 'foo': 3, 'bar': 4}
    
    0 讨论(0)
  • 2021-02-05 15:56

    How about this?

    class foo:
        def __init__(self, arg1, arg2, arg3):
            for _prop in dir():
                setattr(self, _prop, locals()[_prop])
    

    This uses the builtin python dir function to iterate over all local variables. It has a minor side effect of creating an extraneous self reference but you could filter that if you really wanted. Also if you were to declare any other locals before the dir() call, they would get added as constructed object's attributes as well.

    0 讨论(0)
提交回复
热议问题