Python | init fonksiyonunun parametrelerini tek tek tanımlamaktan kurtulma

class Person:

def __init__(self,name,job,jobtype,rank,school,relationship,feel,age,country):

    self.name = name

    self.job = job

    #...

yukarıda görmüş olduğunuz kodda init fonksiyonuma atamış olduğum parametreler var. tek tek her bir parametrem için " self.parametreismi = parametreismi " formülünü kullanmak istemiyorum. onun yerine, bu init fonksiyonumun içerisindeki bütün parametrelerin her birine tek satırda bu işlemi uygulayacak bir metoda veya komuda ihtiyacım var. bunu yapabilir miyim? yapabilirsem nasıl? teşekkürler…

inspect modülü ve locals() sözlüğü ile yapılabilir…

1.adım fonksiyonun içerisinde parametrelerin isimlerini elde etmek. Bunun için inspect.getfullargspec fonksiyonunu kullanıyoruz:

>>> import inspect

>>> def fun(isim, sehir, sira=4):
        print(inspect.getfullargspec(fun))

>>> fun("ad", "vilayet", 5)
FullArgSpec(args=['isim', 'sehir', 'sira'], varargs=None, varkw=None,
            defaults=(4,), kwonlyargs=[], kwonlydefaults=None, annotations={})

Döndürdüğü bir namedtuple objesi, birçok şey barındırıyor; bizim aradığımız ise .args alanında bulunyor: fonksiyonun parametrelerinin isimlerinin listesi. (inspect.getfullargspec kodun herhangi bir yerinde çağrılabilir; fonksiyonun içerisinde bize lazım olduğundan orada çağırdık.)

2.adım o parametrelerin değerlerini elde etmek. Bir fonksiyonun (veya metodun) parametreleri o fonksiyona yerel olan değişkenlerdir, locals() sözlüğü ile ulaşılabilinir:

>>> def fun(isim, sehir, sira=4):
        print(locals())

>>> fun("ad", "vilayet", 5)
{'isim': 'ad', 'sehir': 'vilayet', 'sira': 5}

Bu zaten parameterlerin değerlerini de veriyor, 1. adıma ne gerek vardı? Eğer olur da fonksiyonun içerisinde bir değişken tanımlarsanız, o da bu sözlüğe girer:

>>> def fun(isim, sehir, sira=4):
        sayi = -24
        print(locals())

>>> fun("ad", "vilayet", 5)                    # v|
{'isim': 'ad', 'sehir': 'vilayet', 'sira': 5, 'sayi': -24}

(Eğer bunu garantiliyorsanız, sırf locals ile de yapabilirsiniz.)

3.adımda ikisini setattr ile birleştiririz. setattr(obj, name, value)'nun yaptığı obj.name = value. Burada name kısımlarını inspect.getfullargspec(...).args ile elde ederiz, karşılık gelen value'ları da locals()'den bakarız.

Dikkat etmemiz gereken bir şey kaldı, o da sizin bu işlemi bir metot üzerinden yapıyor olmanız. İlk parametre self olduğundan onu atlayacağız.

Dolayısıyla:

class A:
    def __init__(self, isim, sehir, sira=4):
        # `self` hariç parametre isimleri
        parametre_isimleri = inspect.getfullargspec(self.__init__).args[1:]
        
        # `locals()`'i kenara koyalım
        lokaller = locals()

        # her parametre ismi için...
        for param_isim in parametre_isimleri:
            # değeri elde ederiz
            param_deger = lokaller[param_isim]        
          
            # `self`'e nitelik ekleme kısmı
            setattr(self, param_isim, param_deger)


a = A("ad", "vilayet", 12)
print(a.isim * a.sira)

2 satıra indirmek mümkün… (ama locals habire çağrılıyor; döngü öncesi lokals = locals() daha iyi olur.)

class A:
    def __init__(self, isim, sehir, sira=4):
        # parametrelerden otomatik atama yapıyoruz (ilerisi için not :))
        for param_isim in inspect.getfullargspec(self.__init__).args[1:]:
            setattr(self, param_isim, locals()[param_isim])

a = A("ad", "vilayet", 12)
print(a.isim * a.sira)

Üstte bahsettiğim, başka bir değişken tanımlamayacağınızdan eminseniz metodun içerisinde, yalnız locals ile şöyle olur:

class A:
    def __init__(self, isim, sehir, sira=4):
        # parametrelerden otomatik atama yapıyoruz (ilerisi için not :))
        for param_isim, param_deger in locals().items():
            # parametrelerdeki `self`'i atlıyoruz
            if param_isim  != "self":
                setattr(self, param_isim, param_deger)

a = A("ad", "vilayet", 12)
print(a.isim * a.sira)
4 Beğeni

YA ABI HARIKA BISEYSIN YEMIN EDIYORUM bak adam yazilimci deği̇l adam YAZILIMIN TA KENDİSİ yemi̇n edi̇yorum bak hari̇ka bi̇şey ben bu kadar güzel yaziyi bloglarda makalelerde görmedi̇m ya BU ADAM PYTHON’IN KENDİSİ Mİ çet bi̇ri̇ bi̇şey söylesi̇n çok teşekkür ederi̇m ŞUAN TAKLA ATIYORUM süper gerçekten çok yardimin dokundu abi̇ vatana mi̇llete faydali bi̇r i̇ş olmuş hayretler i̇çeri̇si̇ndeyi̇m gerçekten ya moni̇toru parçalicam çalişti valla çalişti ya bende seni̇n gi̇bi̇ yazilimci olmak i̇sti̇yorum abi̇ tavsi̇yeleri̇n varmi geli̇şmem i̇çi̇n bi̇rkaç tavsi̇ye versen yeterli̇ çok sağol

4 Beğeni

:d rica ederim, o kadar da abartılacak bir şey değil aslında :d Pratik yaparak, resmi dokümantasyon/tutorial’leri okuyarak devam edebilirsiniz. Başkalarının sorularını yanıtlamaya çalışmak, onlara gelen yanıtları incelemek de eklenebilir; Stackoverflow’daki eski (popüler)/yeni sorular bunlar için uygun. Kolay gelsin.

3 Beğeni