There is an existing class whose __init__()
already takes a varying number & types for its arguments. I wish to subclass to add a new argument. I do not know how I am intended to write the subclass's new __init__()
definition.
I do not have the source for the existing base class (it's probably written in C++). help(QListWidgetItem)
gives me:
class QListWidgetItem(sip.wrapper)
| QListWidgetItem(parent: QListWidget = None, type: int = QListWidgetItem.Type)
| QListWidgetItem(str, parent: QListWidget = None, type: int = QListWidgetItem.Type)
| QListWidgetItem(QIcon, str, parent: QListWidget = None, type: int = QListWidgetItem.Type)
| QListWidgetItem(QListWidgetItem)
My editor (PyCharm) recognises these and offers context-sensitive completion. It behaves as though they have been declared via @overload
directives, and I wish to retain that.
Note that already not only is the number of arguments variable but also so are the types. For example, looking through all the overloads parameter #1 might be a QListWidget
, a str
, a QIcon
or a QListWidgetItem
, or not even supplied, and depending on that influences what the second argument can be, etc.
I wish to add an extra one:
MyListWidgetItem(text: str, value: QVariant, parent: QListWidget = None, type: int = QListWidgetItem.Type)
Note that my new QVariant
argument is in second place, and I wish it to be positional not keyword-named.
So I need to recognise this new one when it's called; I need to pull out my new value: QVariant
to set my new member variable, I also need to remove it before calling the base class constructor .
I know that for the declaration I will be adding an overload like:
class MyListWidgetItem(QListWidgetItem)
@overload
def __init__(self, text: str, value: QVariant, parent: QListWidget=None, type: int=QListWidgetItem):
pass
(I assume that will leave the existing QListWidgetItem
@overload
s still available via my derived MyListWidgetItem
s?)
What about for the actual definition? What does it do and how should it be declared/written?
I need to recognise this new one when it's called; I need to pull out my new value: QVariant
to set my variable, I also need to remove it before calling the base class constructor.
I can only guess: is it my job in order to recognise my case to write like:
if len(arguments) >= 2:
if isinstance(arguments[0], str) and isinstance(arguments[1], QVariant):
self.value = arguments[1]
del arguments[1]
Then: Am I supposed to write the single __init__()
definition (not @overload
declarations) for my new sub-class along the lines of:
def __init__(self, *__args)
...
super().__init__(*__args)
or with distinct, explicit, typed arguments along the lines of:
def __init__(self, arg1: typing.Union[QListWidget, str, icon, QListWidgetItem, None], arg2: typing..., arg3: typing..., arg4)
...
super().__init__(arg1, arg2, arg3, arg4)
The latter looks complicated? Is the former approach declaring and working directly off *__args
the best way to go?
[EDIT: If it makes any difference for producing some kind of solution, I am willing to make my new parameter optional via value: QVariant = ...
. Or, if the answer is, say, "You won't be able to do it quite your way because ..., but the better way to do this is to make it a named-keyword-only argument because then you can ...", or whatever, I would consider in that light.]