Show HN: Wat – Python nesnelerinin derinlemesine incelenmesi
(github.com/igrek51)- WAT, Python çalışma zamanında bilinmeyen nesnelerin ne olduğunu hızlıca anlamak için kullanılan bir inspector'dır; type, value, attribute, method, parent type, signature, documentation ve source code'u tek seferde gösterebilir
- Temel kullanım
wat / objectşeklindedir vewat(object)ile aynı şekilde çalışır; ayrıcawat.short / 'foo','foo' | wat.short,wat('foo', short=True)gibi çeşitli sözdizimlerini destekler .short,.dunder,.long,.code,.caller,.public,.all,.ret,.strgibi modifier'lar zincirlenerek çıktı kapsamı, dönüş biçimi, renkli çıktı ve çağrı konumu ayarlanabilir- Kurulum
pip install watardındanimport watile yapılabilir; hızlı debug için aynı Python oturumunda kurulum yapmadan kullanılabilen Insta-Load snippet'i de sunulur - Django
User,re.match,pathlib,colorsys.hsv_to_rgb,typing.List[str],str | Nonegibi örnekler, WAT'in debug, REPL keşfi ve Python iç yapısını öğrenme için kullanılabileceğini gösterir
WAT ne yapar
- WAT, Python nesnelerini çalışma zamanında keşfetmek ve incelemek için kullanılan bir araçtır
- Bilinmeyen bir nesnenin ne olduğunu anlamak zor olduğunda, Python konsolunda
watinspector'ı ile nesnenin yapısı araştırılabilir - Herhangi bir
objectiçinwat / objectçalıştırıldığında şu bilgiler görülebilir- nesnenin type'ı
- biçimlendirilmiş değeri
- değişkenleri ve method'ları
- parent type'ları
- signature
- documentation
- source code
- Aynı derin inceleme
wat(object)sözdizimiyle de kullanılabilir Wat, İngilizcewhatsözcüğünün bir varyasyonu olarak, kafa karışıklığı veya hoşnutsuzluk ifade etmek için kullanılan bir söz olarak tanıtılır
Temel kullanım ve sözdizimi
- Hızlı yazım için bölme operatörü kullanılır
wat / foo,wat(foo)ile aynıdır
- Aynı inceleme için birden fazla sözdizimi kullanılabilir
wat.short / 'foo': hızlı yazım için sözdizimiwat.short('foo')wat('foo', short=True): doğal Python sözdizimi'foo' | wat.short: Unix pipe tarzı sözdizimi
wat.modifier / foobiçimiyle inceleme davranışı ayarlanabilir- Modifier'lar zincirlenebilir; örnek olarak
wat.short.str.gray / 'foo'verilir - Python'da nesneler yalnızca veri yapılarından ibaret değildir; function, class, module ve built-in type'ları da içerdiğinden
wat, her türlü nesneyi keşfedebilir - Interpreter'da
watyazıldığında,watnesnesinin kendisiyle ilgili yardım görülebilir
Modifier'larla inceleme kapsamını ayarlama
.shortveya.s, nesnenin içindeki değişken ve method gibi attribute'ları gizler; yalnızca value, type, parent type, signature ve documentation çıktısını verir.dunder,__ile başlayan dunder attribute'ları gösterir.long, kısaltılmamış value ve docstring'i gösterir.code, function, method ve class'ların source code'unu gösterir.nodocs, function ve class documentation'ını gizler.caller, incelemenin nasıl ve nereden çağrıldığını gösterir; REPL dışında, dosya içinde çalışır.public, private attribute'ları gizler ve yalnızca public attribute'ları gösterir.all, mümkün olan tüm bilgileri içerir.ret, incelemeden sonra nesneyi tekrar döndürür.str, çıktı yazdırmak yerine sonuç string'ini döndürür.gray, konsoldaki renkli çıktıyı devre dışı bırakır.color, konsolda renkli çıktıyı zorunlu kılarwat.localslocal değişkenleri,wat.globalsise global değişkenleri inceler
Kurulum ve Insta-Load
- pip ile kurulum akışı şöyledir
pip install wat- Python içinde
import wat
watpaketinin harici bağımlılığı yoktur- Hızlı debug için, aynı Python oturumunda kurulum yapmadan kullanılabilen Insta-Load yöntemi sunulur
- Insta-Load,
base64vezlibimport edildikten sonra sıkıştırılmış ve encode edilmiş kod string'ini geri açıpexec(..., globals())ile çalıştıran bir Python snippet'inin interpreter'a yapıştırılması şeklinde çalışır - Insta-Load snippet'i çalıştırıldıktan sonra
watobject'i kullanılabilir - Snippet çalıştırılmadan önce içeriğinin doğrulanması önerilir
print(zlib.decompress(base64.b64decode(code)).decode())ile çıkarılan kod içeriği önceden görülebilirinspection.pyiçeriğini interpreter'a yapıştırmak da aynı etkiyi verir- paketi pip ile kurup kodu inceleme yöntemi de önerilir
- WAT, tek bir Unicode glyph üzerinden yüklenebilir
- Unicode string tabanlı loader, uzun emoji ve birleşik karakter string'lerini
ord(c) & 255ile byte dizisine çeviripzlib.decompress(...)sonrasındaexec(...)ile çalıştırır
Nesne type'ını ve kullanımını anlama
- Dinamik tipli bir dil olan Python'da nesne type'ını anlamak bazen zor olabilir; WAT Inspector, type adını ve bu type'ın geldiği module'ü gösterir
- Type kontrolü örnekleri, value, type ve length bilgisini birlikte gösterir
wat.short / (1,),(1,)value'sunu,tupletype'ını ve1length'ini çıktılarwat.short / {None},{None}value'sunu,settype'ını ve1length'ini çıktılar
- Django
Usernesnesi örneğindewat.short / user,str: admin,repr: <User: admin>,django.contrib.auth.models.Usertype'ı ve parent type listesini çıktılar - Gerçek type görüldükten sonra, ilerideki karışıklığı azaltmak için koda type annotation eklenebilir
- Bilinmeyen bir nesnenin nasıl kullanılacağını anlamak için method listesi, signature ve docstring çıktılanabilir
- örnek olarak
wat / ['foo']verilir - docstring'in tamamını görmek için
wat.longkullanılır
- örnek olarak
- Bir function'ın kullanımını anlamak için function'ın docstring'i ve signature'ı görülebilir
- örnek olarak
wat / str.splitverilir
- örnek olarak
Attribute, module ve source code keşfi
- İncelenen nesnenin içini görmek için attribute'lar ve her attribute'un type'ı listelenebilir
- örnek olarak
wat / re.match('(\\d)_(.*)', '1_title')verilir
- örnek olarak
- Module keşfi için de kullanılabilir; seçilen module'ün function, class ve alt module'leri listelenebilir
import pathlibardındanwat / pathlibçalıştırılan bir örnek bulunur- sonrasında
wat / pathlib.fnmatchgibi daha derine inilebilir
- WAT Inspector, varsayılan olarak
__ile başlayan attribute'ları gizlerwat.dunder / {}ile dunder attribute'ları görülebilir
- Bir function'ın gerçekte nasıl çalıştığını görmek için source code görüntülenebilir
import colorsysardındanwat.code / colorsys.hsv_to_rgbçalıştırılan bir örnek bulunur
- İç içe dict ve list yapıları, girintili ve okunabilir bir biçimde formatlanır
Debug oturumu ve değişken inceleme
- Python'un
breakpoint()özelliğiyle etkileşimli debugger çalıştırıldıktan sonra, nesneler o anda incelenebilir - Pdb örneğinde
import watveya Insta-Load snippet'ini yapıştırdıktan sonrawat / fooile local değişken incelenir vecile yürütmeye devam edilir - Local ve global değişkenler sırasıyla
wat.localsvewat.globalsile görülebilir wat()parametresiz çağrıldığında, çağıranın stack'indeki local değişkenleriLocal variablesbaşlığı altında yazdırır
Python iç yapısını öğrenme örnekleri
- Python'un iç çalışma biçimini anlamaya yönelik öğrenme örnekleri de yer alır
reversed([]) == reversed([])ifadesiFalsedöndürür;wat.s / reversed([])ise value'nunlist_reverseiteratornesnesi olduğunu ve type'ınınlist_reverseiteratorolduğunu gösterirwat / type('ObjectCreator', (), {}), dinamik olarak oluşturulmuş class'ın value'sunu,typetype'ını vesignature: class ObjectCreator()bilgisini gösterirwat / type,typenesnesinin kendi value'sunu,typetype'ını,class type(…)signature'ını,type(object) -> the object's type,type(name, bases, dict, **kwds) -> a new typedocumentation'ını vemrogibi public attribute'larını gösterirwat.s / List[str],typing.List[str]value'sunu,typing._GenericAliastype'ını,typing._BaseGenericAlias,typing._Finalparent type'larını vedef List(*args, **kwargs)signature'ını gösterirwat(str | None),str | Nonevalue'sunu vetypes.UnionTypetype'ını gösterir- Python built-in nesnelerini keşfetme örnekleri olarak
wat / __builtins__,wat / ...verilir - WAT'in kendisi de incelenebilir
- örnek olarak
wat.dunder / wat,wat.code / wat.__truediv__verilir
- örnek olarak
İç çalışma özeti
inspect_format(obj, *, short=False, dunder=False, nodocs=False, long=False, code=False, caller=False, public=False, all=False), nesne inceleme sonucunu bir string olarak oluştururall=Trueisedunder,long,code,callerbirlikte etkinleştirilirpublic=Trueise private çıktı devre dışı bırakılırsys.stdout.isatty()true ise terminal genişliği alınır ve çıktının üstüne ve altına─ayraçları eklenir
- İnceleme çıktısı; nesne value'su, string gösterimi, type, parent type, length, signature, documentation, source code ve attribute bölümleri sırasıyla oluşturulur
- Attribute incelemesi
dir(obj)üzerinde ada göre sıralı dolaşır- dunder attribute'lar,
dunderayarı kapalıysa hariç tutulur _ile başlayan private attribute'lar, private ayarı kapalıysa hariç tutulurgetattr(obj, key)sırasındaBaseExceptionoluşursa, exception nesnesi value olarak kullanılır
- dunder attribute'lar,
- Callable nesnelerde signature,
inspect.signature(obj)temel alınarak formatlanır- başarısız olursa
(...)biçiminde yedek bir signature döndürülür - class'lara
class, coroutine function'laraasync def, function, method, built-in veya__name__taşıyan nesneleredeföneki eklenir
- başarısız olursa
code=Trueolduğunda ve nesne bir class ya da callable ise,inspect.getsource(obj)ile source code çıktılanırOSError,TypeError,IndentationErroroluşursa başarısızlık mesajı döndürülür
- dict ve list formatter'ları, girinti derinliği 30'u aşarsa
ERROR: too deeply nesteddöndürür
Renkli çıktı ve tema
- Ortam değişkenleriyle renkli çıktı kontrol edilebilir
WAT_COLOR="false", konsoldaki renkli çıktıyı devre dışı bırakırWAT_COLOR="true", non-tty ortamlarda bile renkli çıktıyı zorunlu kılar
WAT_COLORSortam değişkeniyle renk teması özelleştirilebilir- Varsayılan tema,
BAR=0;34,TRAIT=1;34,HEAD=1;37,STR=0;32,NUMBER=0;31,NONE=0;35,TRUE=1;32,FALSE=1;31,DOCS=2;37,KEYWORD=0;34,CALLABLE=1;32,VARIABLE=1;33,CODE=0;33biçiminde ANSI renk kodu eşlemesidir _strip_color(text), ANSI escape sequence'leri regex ile temizler
İlham
- WAT, Rich Inspect'ten ilham almıştır
1 yorum
Hacker News yorumları
Vay canına, gerçekten harika. Eskiden benzer bir amaç için python-ls[0] kullanıyordum ama hatırlamadığım bir nedenle bir şeyler bozuldu ve artık bakımı da yapılmıyor
Bunu büyük ölçüde snoop[1] ve pdbpp'den oluşan hata ayıklama araç kutuma eklemeyi düşünüyorum. wat'tan tek isteğim, Jupyter'de nesne keşfini kolaylaştıracak bir ipy widget olurdu
base64 exec hack'i de hoşuma gitti. Python'u uzun zamandır kullanıyorum ama bunu şimdiye kadar ne düşünmüştüm ne de görmüştüm; ileride birkaç amaç için kesinlikle deneyeceğim
[0] https://github.com/gabrielcnr/python-ls
[1] https://pypi.org/project/snoop/
Eğlenceli görünüyor. Python'da her zaman dir kullanıyorum ve belgelerin zayıf olduğu durumlarda bazen resmî dokümanlardan bile daha faydalı olabiliyor
Etkileşimli kabuk Python'un gerçek güçlü yanlarından biri ama etrafında bunun gibi daha fazla yeni araç ya da yenilik olmaması şaşırtıcı
Eski icecream'in daha gösterişli bir sürümü gibi görünüyor
https://github.com/gruns/icecream
Bilmiyorsanız aşağıdaki diğer diller için uygulama listesine de bakın
https://github.com/gruns/icecream#icecream-in-other-language...
Bu tür araçlar faydalı oluyor
20 yıl önce Zope için bir nesne introspector'ü yapmıştım
Bugünlerde her gün devtools kullanıyorum, icecream ve q'yu da ara sıra kullanıyorum. wat'ı da bir deneyeceğim
from wat import watProjenin karakteri bu kadar havalıyken, aynı kullanım sözdizimiyle düz
import watsunmaması şaşırtıcı. Böylece meraklı kullanıcıların wat/wat deneyip numarayı keşfetmesi de sağlanabilirdiimport watgüzel olurdu ama Python'da modülleri çağrılabilir hâle getirememe kısıtı var. Bu yüzden daha uzun olanfrom wat import watyoluna gidilmişEmin değilim ama
import wat; wat.wat / objectdaha kullanışlı da olabilirÇok faydalı görünüyor ama okunabilirlik adına tamamen ilgisiz operatörlerin, burada
/operatörünün, aşırı yüklenmesi yönündeki son eğilimden rahatsız olan tek kişi ben miyim diye merak ediyorum/aşırı yüklemesinin tuhaf bir seçim olduğuna katılıyorum. Yine deis'in aşırı yüklenememesi üzücü. Gerçektewat(foo)tek başına da yeterli olurdu gibi geliyorUğraştırıcı import'tan kaçınmak için
$PYTHONSTARTUPdosyasına şunları da ekleyebilirsiniztry:from wat import watexcept ImportError:passSonunda onun çıktısını yazdırıp, her zaman kullanılabilsin diye
PYTHONPATH'in işaret ettiği dizine koydumSürekli kullanır mıyım, göreceğiz
Vay, Python öğrenirken böyle bir araç olsaydı oyunun kurallarını değiştirirdi diye düşünüyorum. Bir dili öğrenirken içeride neler olduğunu görmek temel yollardan biri ama Python'un varsayılan hata ayıklaması en iyi ihtimalle hayal kırıklığı yaratıyor
Bunun yerine pry kurup koyu bir Ruby hayranı olmuştum ama bu araç Python'u yeniden denememe neden olabilir
Yazar, işlevselliği sağlamak için arka planda standart kütüphanedeki Python inspect modülünü kullanıyor. Elbette bunun üzerine çok fazla ek değer katmış
wat modülündeki
inspection.pydosyasına bakabilirsiniz2. satırda şunu görüyorsunuz:
import inspect as std_inspect“Bir şeyi hızlıca debug etmek istiyorsanız, aynı oturumda hiçbir şey kurmadan bu inspector'ü kullanabilirsiniz”
“Bu snippet'i Python yorumlayıcısına yapıştırıp anında yükleyin”
Proje README'sine tüm projenin bir kopyasını base64 ile kodlanmış sıkıştırılmış veri olarak koyma fikri oldukça dahiyane
Özellikle gerçekten ihtiyaç duyulacak ortamlara önceden koymayı düşünmemiş olabileceğiniz bu tür projeler için çok uygun