1

How to use an if statement or similar in function arguments to reduce blocks of code?

    if versionid is None:
        s3_response = s3_client.head_object(
              Bucket=bucket
            , Key=key
            )
    else:
        s3_response = s3_client.head_object(
              Bucket=bucket
            , Key=key
            , VersionId=versionid
            )

to something like this:

        s3_response = s3_client.head_object(
              Bucket=bucket
            , Key=key
            , if versionid is not None: VersionId=versionid
            )

Not able to get this working and can't find any examples so assume not possible.

Paul
  • 578
  • 1
  • 8
  • 23
  • 2
    [Does Python have a ternary conditional operator?](https://stackoverflow.com/q/394809/1258041) – Lev Levitsky Jun 24 '22 at 14:34
  • You can use the conditional operator to choose different values of the argument based on a condition, but not whether to provide the argument or not. – Barmar Jun 24 '22 at 14:41

1 Answers1

3

You can't use a statement where an expression is expected. Unless you know what the default value (if any) for the VersionId parameter is, you can do something like this:

args = {'Bucket': bucket, 'Key': key}
if versionid is not None:
    args['VersionId'] = versionid

s3_response = s3_client.head_object(**args)

If you do know the appropriate default, you can use the conditional expression:

# FOO is whatever the appropriate default is
s3_response = s3_client.head_object(Bucket=bucket, Key=key, Versionid=FOO if versonid is None else versionid)

(Assuming a non-None versionid will be a truthy value, you can shorten this to versionid or FOO, but be aware that 0 or FOO is 0, not FOO.)


You could write something like

s3_response = s3_client.head_object(
                Bucket=bucket,
                Key=key,
                **({} if versionid is None else {'VersionID': versionid})
              )

but I wouldn't recommend it.

chepner
  • 497,756
  • 71
  • 530
  • 681
  • The first example is perfect here because it requires a string if sending, so None will not work, and I have no default. This is all super useful knowledge, cheers. – Paul Jun 24 '22 at 15:59
  • 1
    Yeah, if using a `**` parameter, then the only distinction to make may be whether the keyword argument is present or not, not whether it has one value or another. – chepner Jun 24 '22 at 16:00