@YAPD: Ich sehe das wie rogerb und hatte ja auch schon geschrieben wie man das ohne ``*args`` und einem Defaultwert löst. Das ist das übliche Idiom für ein optionales Argument, das man das entweder mit `None` als Defaultwert vorbelegt, oder einem extra erzeugten, einmaligen ”Nicht-Wert”, falls `None` ein gültiger Wert sein darf. Dann fällt das Beispiel mit dem zusätzlichen "Neu" auch weg, weil darum kümmert sich Python dann schon eine Ausnahme zu erzeugen wenn man das versucht. Und der erste ``elif``-Zweig macht keinen Sinn, weil es nicht mehr als ein Positionsargument geben kann.
Da sind bei den Bedingungen ein paar Klammern zu viel.
Das `isinstance()` kann man zu einem zusammenfassen, weil man als zweites Argument auch ein Tupel mit Typen übergeben kann.
Aber eigentlich sollte man das weglassen, denn das verhindert „duck typing“. Den Fall mit dem Wörterbuch würde man einfach weg lassen und davon ausgehen, dass es sich um eine Zeichenkette handelt. Denn wenn, wie ich mal vermute, das Wörterbuch die gleiche Bedeutung haben soll wie beliebige Schlüsselwortargumente, dann kann man den Aufrufer der ein Wörterbuch hat, das beim Aufruf auch einfach per ** übergeben lassen. Schon braucht man keinen extra Code mehr.
Falls den Typ des Positionsarguments an der Stelle tatsächlich prüfen muss, um dann etwas anderes zu machen, würde ich nur auf einen Typen testen und zwar auf den, bei dem es unwahrscheinlicher ist, dass da jemand versucht eine Ente zu übergeben, also einen Typen der sich so verhält wie eine Zeichenkette, aber nicht von `str` abgeleitet ist. Denn das jemand eine Abbildung implementiert, die aber per `isinstance()` nicht als solche erkennbar ist, halte ich für wesentlich wahrscheinlicher, als dass das jemand mit einer Zeichenkette machen würde. Also:
Code: Alles auswählen
def example(uid, arg):
if isinstance(arg, str):
do_something_with_text(arg)
else:
do_something_with_mapping(arg)
Wobei die beiden Zweige nicht so unabhängig sein dürfen, denn sonst würde man dafür zwei verschiedene Funktionen schreiben. Also das wäre eher so etwas:
Code: Alles auswählen
def example(uid, arg):
do_something_with_mapping(
convert_text_to_mapping(arg) if isinstance(arg, str) else arg
)