Tekil Mesaj gösterimi
Alt 27-01-2019 15:11  
  • Gbmdpof
  • AR-GE Tim
  • Üye Bilgileri
Üyelik tarihi
09/2016
Mesajlar
Konular

Teşekkür (Etti):
Teşekkür (Aldı):


Canlı Python Nesnelerini İnceleyin - inspect



Bu gün Interaktif Mod ile bir şey üzerinde çalışırken, burada yazdıklarımı artık dosyaya geçirebileceğimi düşündüm fakat ardından fark ettim ki yazdığım fonksiyonların çoğu oldukça geride kalmıştı. Ardından ise bu güzel inspect modülünü keşfettim.

inspect modülü, modüller, sınıflar, metodlar, fonksiyonlar, tracebakler, frame nesneleri ve kod nesneleri gibi canlı nesneler hakkında bir çok bilgiyi almaya yarayan işe yarar fonksiyonlar sunan bir modüldür. Örnek olarak bir sınıfın metodlarına erişebilir, benim yaptığım gibi o metodların kaynak koduna ulaşabilir, bir fonksiyon için argüman listesi çıkarabilir veya detaylı bir traceback göstermek için gereken tüm verileri alabilirsiniz.

Bu modül tarafından sunular dört temel hizmet vardır: tür kontrolü, kaynak kodunu alma, sınıf ve fonksiyon inceleme ve interpreter stack'i inceleme.

Ben, bu yazıda sadece karşınıza daha çok çıkabilecek örnekler üzerinden gideceğim fakat inspect modülünün tam kullanımı için orijinal dökümantasyona bakabilirsiniz: https://docs.python.org/3/library/inspect.html

Bu modülü incelemeye başlamak için örneklerde kullanmak için bir modül yazalım:

Kod:
class class1:
    def __init__(self, arg1):
        self.arg1 = arg1

    def sum(self, arg2):
        return self.arg1 + arg2

class class2(class1):
    def multiply(self, arg2):
        return self.arg1 * arg2

def func1(arg1):
    return arg1 ** arg1

obj = class2()
Şimdi ise bu modülü importlayalım ve ardından bütün inspect.getmembers ile incelemeye başlayalım:

Kod:
import sample
import inspect

for name, value ininspect.getmembers(sample):
    if not name.startswith('__'):
        print(name, value)
Bu kodu çalıştırınca ise __ ile başlayanlar dışında (built-in olarak gelen ve şu an ihtiyacımız olmayan şeyler) modülün bütün üyelerini bize gösteriyor.

Kod:
λ python3 inspector.py
class1 <class 'sample.class1'>
class2 <class 'sample.class2'>
func1 <function func1 at 0x7fd2a84d16a8>
obj <sample.class2 object at 0x7fd2a84b20f0>
inspect.getmembers fonksiyonu, aynı zamanda isteğe bağlı bir argüman daha alıyor. Bu argüman ile de sadece verdiğimiz türe uyan üyeler dönüyor. Örneğin sadece sınıfları almak istersek, kodumuzu aşağıdaki şekilde değiştirebiliriz.

Kod:
import sample
import inspect

for name, value ininspect.getmembers(sample, inspect.isclass):
    print(name, value)
Bunda ise çıktı, sadece sınıfları aldığımız için yukarıdakinin ilk 2 satırı olacak.

Kod:
λ python3 inspector.py
class1 <class 'sample.class1'>
class2 <class 'sample.class2'>
Aynı zamanda sadece modülleri değil, modüllerin içindekiler hakkında da bilgi alabiliriz. Örneğin class1'in içindeki fonksiyonları bulan bir script yazalım.

Kod:
import sample
import inspect

print(inspect.getmembers(sample.class1, inspect.isfunction))
Bu da sınıfımızda sadece __init__ ve sum fonksiyonları olduğu için onları printleyecektir. Çıktımız da şu şekilde olacaktır.

Kod:
λ python3 inspector.py 
[('__init__', <function class1.__init__ at 0x7f1a0dc1dc80>), ('sum', <function class1.sum at 0x7f1a0dc1dd08>)]
Aynı şekilde sınıfları inceleyebildiğimiz gibi nesneleri de inceleyebiliriz. Ki bu bazen nesne hakkında fazla bilgiye sahip olmadığımızda oldukça işimize yarayabilir. Ayrıca bir sınıfın kullanımı hakkında bilgiye sahip olmadığımızda da docstringleri okumamız gerekebiliyor. Bunu normalde __doc__ ile elde edebilsek de inspect modülü ile temizlenmiş bir şekilde docstring'i ekle edebiliyoruz.



Bu temizleme hakkında daha fazla bilgi için CPython kaynak kodundan inspect.py dosyasında işaretlediğim satırları inceleyebilirsiniz: https://github.com/python/cpython/bl...t.py#L616-L643

Şimdi ise beni dakikalarca yukarı ok tuşuna basmaktan kurtaran kaynak kodu okuma özelliğine bakalım. Örneğin, class1'in kaynak kodunu okuyalım bunun için:

Kod:
import sample
import inspect

print(inspect.getsource(sample.class1))
Çıktı olarak, kaynak kodumuzu verdi:
Kod:
λ python3 inspector.py 
class class1:
    def __init__(self, arg1):
        self.arg1 = arg1

    def sum(self, arg2):
        return self.arg1 + arg2
Bu getsource'un bir diğer güzel yanı ise yorum satırları ve docstringleri de bize vermesidir:
Kod:
class class1:
    def __init__(self, arg1):
        self.arg1 = arg1 # set self.arg1

    def sum(self, arg2):
        """sum function"""
        return self.arg1 + arg2
Ayrıca kaynak kodunu almadan bir metodun argüman olarak neler aldığını öğrenmek istersek de bu metodun imzasını inspect.signature ile alabiliriz:

Kod:
import sample
import inspect

print(inspect.signature(sample.func1))
Kod:
λ python3 inspector.py
(arg1)
Ben burada örnek bir fonksiyon yazdığım için argüman adını açıklayıcı olmayan arg1 yapmıştım fakat normalde açıklayıcı argümanlar bulmanız daha olası. Sizin de kod yazarken argüman adlarınızı dikkatli seçmenizde fayda var bu sebepten.

Evet, bunlar ile artık Python nesneleri hakkında detaylı bilgiye sahip olabiliyoruz. Eğer bu modülü kullanarak bir şeyler yazmak isterseniz, kendi dökümantasyon oluşturucunuzu yazabilirsiniz.



___________________________________________

~humanity is overrated~
 Offline  
 
Alıntı ile Cevapla
 

wau