0

I'm working on a python module that fetches, downloads/updates and then automatically installes other modules. How do I use **kwargs (or an alternative) without needing =True on the end for a "flags" system?

I'm not very experienced in general so I'm not sure what do do here

Currently, for the silent flag to work, It has to look like this:

pyup.imp(["psutil","shutil","os","sys","pyinstaller"],silent=True)

but I want the call function to look like this:

pyup.imp(["psutil","shutil","os","sys","pyinstaller"],silent)

The function itself looks like this (in pyup.py):

def imp(libs = [], *args, **kwargs):

where libs[] is the array containing the wanted libraries.

How do I make the function call not require "=True"?

Auxilor
  • 49
  • 1
  • 8
  • 1
    There are ways of making this work but beware that this wouldn’t be “pythonic” and is therefore generally discouraged. – Konrad Rudolph Apr 29 '19 at 14:34
  • 2
    As a side note, be very careful with a mutable default argument (https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument) – DeepSpace Apr 29 '19 at 14:37
  • 1
    To me, the notation `imp([...], silent)` implies that silent is some sort of local variable passed to the function. `silent=True` is more readable in my opinion. – TheHowlingHoaschd Apr 29 '19 at 14:38
  • The way to make that happen would be for either a) `silent` to be explicitly positional (`imp(libs, silent, *args, **kwargs)`) or b) for you to imply where `silent` is in `*args` like `silent, *args = args`. Also, you don't want `lists` or other mutable data structures to be defaults in functions – C.Nivs Apr 29 '19 at 14:38
  • Python prefers being explicit, and `silent=True` is explicit. So I'd recommend using what you have. – wjandrea Jun 22 '19 at 00:56

2 Answers2

1

If you want to pass a series of string flags to your function (as if it were a terminal application), you coud pass them as unnamed positional arguments via *args.

def imp(libs=[], *args):
    silent = '--silent' in args

# somewhere else
imp([...], '--silent')
  • They would need to be strings though, i don't think your notation can be made to work in python. – TheHowlingHoaschd Apr 29 '19 at 14:46
  • This works well. Just wondering, would it be possible to "declare" --silent as a blank variable or something similar to acheive a call like: ```python imp([...], --silent)``` – Auxilor Apr 29 '19 at 14:50
  • No that's not possible. If you insert a name like that, python will always look for it in the scope where the function is called. Only the `silent=True` syntax interprets `silent` in the scope of the function (or passes it to `**kwargs` if no parameter `silent` is defined). – TheHowlingHoaschd Apr 30 '19 at 13:05
0

If we defined a function like this, you cannot:

def imp(libs = [], *args, **kwargs):

But if you defined the function like this, you can:

def imp(libs = [], silent = True, *args, **kwargs):

and indeed, just as you posted, you can have this run without problem:

silent = True
imp(["psutils", ...], silent)

only that inside the function, kwargs will never have the key silent as it is being held by another parameter.

adrtam
  • 6,991
  • 2
  • 12
  • 27