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)