Argumenty funkcji

0

W jaki sposób można obsłużyć by konstruktor w pythonie przyjmował argumenty w takich formatach

def __init__(imie, nazwisko= Nowak):
    ...

dane(Jan, Kowalski) oraz dane(Imie = Jan, Nazwisko =Kowalski)

Jak potem dostać się do takiej zmiennej w konstruktorze?

0

Nie rozumiem, o co pytasz. Ale podejrzewam, że Twój problem wynika z tego, że Twoje wywołanie (dane(Jan, Kowalski)) ma sens tylko wtedy, jeśli masz wcześniej zmienne Jan oraz Kowalski. Tobie pewnie chodziło o stringi "Jan", "Kowalski".

A oprócz tego, w Pythonie __init__ przyjmuje jako pierwszą zmienną klasę którą obsługuje, co zazwyczaj zapisuje się jako def __init__(self, imie, nazwisko=Nowak).

0

Zapewne chodzi o użycie argumentów *args and **kwargs a potem w ciele initalizatora uzyskanie z nich odpowiednich danych i przypisanie do self.imie i self.nazwisko
https://pythontips.com/2013/08/04/args-and-kwargs-in-python-explained/

0

Nie do końca to miałem na myśli.

Mam takie coś

class Dane:

    def __init__(self, Imie, Nazwisko="Kowalski"):
        Imie = self.Imie
        Nazwisko = self.Nazwisko

Podczas takiego użycia nie ma problemu:

a =  Dane("Arkadiusz", "Nowak")
b= Dane(Imie ="Arkadiusz", Nazwisko= "Nowak")

Podczas wywołania:

c =  Dane(Imie ="Arkadiusz", "Nowak")

otrzymuję taki błąd ze wskazaniem na "Nowak" positional argument follows keyword argument
Co tu poprawić?

0

Zamiast :
Imie = self.Imie
Nazwisko = self.Nazwisko

odwrotnie:
self.Imie = Imie
self.Nazwisko = Nazwisko

2

Argument, który ma zdefiniowaną wartość domyślna musi być po pozycyjnych; nie Możesz też ze zwykłego (pozycyjnego) argumentu zrobić domyślny.

0

To jak inaczej przypisać domyślną wartość dla argumentu w konstruktorze?

0

Przestudiuj ten kod, Możesz dodać więcej opcji:

class Foo:
    def __init__(self, given  = "Jan", surename="Kowalski"):
        self.given = given
        self.surename = surename

f1 = Foo()
print(f1.given, f1.surename)
f2 = Foo("John")
print(f2.given, f2.surename)
f3 = Foo("Donald", "Trump")
print(f3.given, f3.surename)

class Bar:
    def __init__(self, given, surename="Kowalski"):
        self.given = given
        self.surename = surename

b1 = Bar("Jan")
print(b1.given, b1.surename)

b2 = Bar("Donald", "Knuth")
print(b2.given, b2.surename)

b3 = Bar() # error  missing 1 required positional argument: 'given'
0

Przypisujesz dobrze. Tylko potem przy wywołaniu to działa inaczej — w Pythonie, tak jak Ci interpreter powiedział, argumenty nienazwane muszą być przed argumentami nazwanymi. Więc możesz wywołać to jako dane("Jan", "Kowalski") (oba nienazwane) czy dane("Jan", nazwisko = "Kowalski") (nienazwany, nazwany); ale nie możesz jako dane("Kowalski", imię = "Jan") (bo imię jest uzupełniane dwa razy, raz domyślnie z "Kowalski", i raz z nazwanego argumentu "Jan") ani jako dane(imię = "Jan", "Nowak"), bo wtedy masz złą kolejność (nazwany, nienazwany).

0

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ę.

0 użytkowników online, w tym zalogowanych: 0, gości: 0