2

I have a project that contains a lot of protobuf messages, and some of these protobufs even include other messages that also have a lot of parameters within.

Because there are so many parameters involved, almost every function that I write uses **kwargs instead of required/optional arguments, so my functions usually look like this:

def set_multiple_params(**kwargs):
    header, smp_message = Writer.createMessage(SetMultipleParametersRequestMessage_pb2.SetMultipleParametersRequestMessage,
                                               TIMESTAMP)
    data = smp_message.multipleParametersData
    data.maxPrice = kwargs['maxPrice'] if 'maxPrice' in kwargs else 15.54
    data.minPrice = kwargs['minPrice'] if 'minPrice' in kwargs else 1.57
    ....

    # list goes here with around 30 more checks like this, and finally
    
    return Writer.serializeMessage(header, smp_message)

Writer is just a small library that uses createMessage function to append the PacketHeader data to the message, while serializeMessage simply calls the serializeToString method, and returns the tuple.

I use this in the way that I create a dict of data which I pass into the **kwargs. My code works, and it's ok with me for now, but it's tedious when I have to write 50 checks like this per function.

So the question is if there is any other way to check the key in **kwargs other than this, or is this my best solution? I know I can use chained if's, but I was wondering if there is something easier or more Pythonic.

Neither of the keys have the identical values, except the booleans. I already use any() function to save myself from writing these parts of the code.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
mutantkeyboard
  • 1,614
  • 1
  • 16
  • 44
  • 1
    @ŁukaszRogalski depends if the OP *always* has default values or whether attributes can be missing on the `data` object... – Jon Clements Dec 12 '16 at 17:09
  • @JonClements that's correct. I don't set the default values on optional fields. In this case I only check if key exists, then I assign it. – mutantkeyboard Dec 12 '16 at 17:13
  • so do you have fields that are effectively required and can't be defaulted? – Jon Clements Dec 12 '16 at 17:15
  • @JonClements no. I always set the defaults to the required fields. I try to minimise the errors. Actually Alex Hall's answer bellow is what I was looking for. I don't work with Python that much these days, so I totally forgot about the `get()` method for keys. But thank you for the insight anyway :) – mutantkeyboard Dec 12 '16 at 17:21
  • 1
    Ahh... I'd refactor slightly then instead of a large list of gets...use a default dict of `defaults = {'maxPrice': 15.4, 'minPrice': 1.57}`... then loop over an updated copy of that and set the attributes on `data`, something like: `for k, v in dict(defaults, **kwargs).items(): setattr(data, k, v)` - that way you can keep the defaults in a single place and just utilise the loop to simplify the LoC... – Jon Clements Dec 12 '16 at 17:24

1 Answers1

4
data.maxPrice = kwargs.get('maxPrice', 15.54)
Alex Hall
  • 34,833
  • 5
  • 57
  • 89