Można zrobić to w pythonie niestety tylko w ramach pewnego porządku, i czasem trzeba się zabezpieczyć odpowiednio, gdyby ktoś chciał stworzyć funkcję kompletnie bez argumentów, chyba że jest ci to obojętne :).
Przykład z zabezpieczeniem że musi być podane imię:
class Dane:
def __init__(self, Imie=None, Nazwisko="Kowalski"):
if not Imie:
raise TwojError("Twoj komunikat błędu")
self.Imie = Imie
self.Nazwisko = Nazwisko
#To pozwoli ci na wywoływanie w taki sposób:
Dane(Imie="Janusz", Nazwisko="Kowal")
Dane("Janusz", Nazwisko="Kowal")
Dane("Janusz", "Kowal")
Dane(Nazwisko="Kowal", Imie="Janusz")
#niestety ostatnie dwie możliwości nie są możliwe:
#Dane(Nazwisko="Kowal", "Janusz")
#Dane(Imie="Janusz", "Kowal)
Wymusza to pewien porządek o którym mówili koledzy wyżej, jeśli chcesz to jeszcze zaostrzyć, powinieneś użyć kwargs, innej metody nie ma:
class Dane:
def __init__(self, **kwargs):
self.Imie = kwargs.pop("Imie") #Jeśli jest to wymagane pole
self.Nazwisko = kwargs.pop("Nazwisko", "Kowal") #Jeśli może mieć wartość domyślną
#Tu jeszcze powinieneś sprawdzić czy kwargs został pusty, jeśli nie, to wyrzucić błąd KeyError jak przy braku wartości i podać jakie pola powinna zawierać definicja klasy.
Dane(Imie="Janusz", Nazwisko="Kowal")
Dane(Nazwisko="Kowal", Imie="Janusz")
#~ Dane(Nazwisko="Kowal") #To wyrzuci KeyError który możesz przechwycić
Dane(Imie="Janusz") #To zadziała dzięki domyślnej wartości w pop
#O poniższych bez sprecyzowania jakie to argumenty, nie masz niestety nawet co myśleć,
#~ Dane(Nazwisko="Kowal", "Janusz")
#~ Dane(Imie="Janusz", "Kowal")
#~ Dane("Janusz", "Kowal")
#~ Dane("Janusz", Nazwisko="Kowal")
Osobiście polecam ostatnią metodę.