Async with deyimi asenkron context manager'ı nasıl kullanıyor?

Aslında tam olarak nereyi anlamadığımı kodlar üzerinde göstersem sorum daha iyi anlaşılacak olduğunu düşünüyorum. Öncelikle şunu belirtmeliyim bu konununorjinali şu linktir. https://www.python.org/dev/peps/pep-0492/#example. İlgilenen ve destek olan arkadaşlarıma şimdiden teşekkür ederim.

#Asenkron Context Manager Fonksiyonu aşağıdaki gibi ve buradaki aenter ve aexit metodları bir korotin olduğu için awaitable nesne döndürüyor ve bu iki metod başka metodları çalıştırırken önce askıya alıp kontrol ediyor eğer metod da sorun yoksa giriş (yani programı çalıştırıyor) eğer verdiğimiz metod sorunluysa programdan çıkış yapıyor.Bir anlamda if else gibi hatta try except desem daha iyi gibi ama asenkron biçimde.

class AsyncContextManager:
    async def __aenter__(self):
        await log('entering context')

    async def __aexit__(self, exc_type, exc, tb):
        await log('exiting context')

#şimdi async with ile bir örnek kod yazalım.

async with EXPR as VAR:
    BLOCK

bu async with deyimli kodu python şöyle okuyor ve anlamlandıramadığım kısımda burası.

mgr = (EXPR)#burası bizim metodumuzun tuple içine alarak değişkene atanan kısmı
aexit = type(mgr).__aexit__#burada asenkron context manager metodu olan __aexit__ kullandık ama nasıl, __aexit__ metodunu nasıl kullanabildik.
aenter = type(mgr).__aenter__(mgr) #aynı şekilde __aenter__ metodunu nasıl kullanabildik.

VAR = await aenter #aşağıdaki BLOCK asenkron çalışıp awaitable bir nesne döndürmesini sağlıyor.
try:
    BLOCK#kod bloğunu çalıştır
except:
    if not await aexit(mgr, *sys.exc_info()):#yukarıdaki __aexit__ metoduyla bir courotin yarattık sanırım burada da eğer oluşmadıysa hataya çıkıyoruz.
        raise
else:#aksi bir durum varsa __aexit__ metoduyla oluşturduğumuz aexit courotini ile askıdaki programımızı(o an çalışan metodu )dan çıkıp onu hata ile sonlandırıyoruz.
    await aexit(mgr, None, None, None)

yukarıdaki kodların yanında yaptığım açıklamalarda anlamadığım yerleri paylaşmaya çalıştım, acaba bana yardımcı olabilir misiniz?Açıklamalar benim anladığım, doğrusu nedir acaba?

Arkadaşlar biraz araştırmayla biraz ilerleme kaydettim, yukarıda

        mgr = (EXPR) # ile biz bir tuple değil generator oluşturuyoruz.
        aenter = type(mgr).__aenter__(mgr) #burada da __aenter__(mgr) mgr parametresi aslında alamaması lazım ama nasıl almış onu bulamadım

o yüzden aşağıdaki örnek üzerinden de cevap verilebilir, cevabını bilen varsa;
Şöyle bir kodumuz olsun ve ben aşağıdaki kodu şöyle kullanabilirim

a = Log() #ve
 a.__enter__() 
#ama
 a.__enter__(a) 

şekinde nasıl yorumluyor python bunu burada düğümlenip kalıyorum:

class Log:
    def __init__(self):
        pass
    def __enter__(self):
        print("__enter__")
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("__exit__")
        

Python’ın metodlara self parametresini nasıl geçtiğini mi soruyorsunuz?

@ismailarilik hocam aslında tam anlamadığım nokta şu ;
class AsyncContextManager tanımlarken async def __aenter__(self, other): olarak tanımlansa
mgr = (EXPR)
aenter = type(mgr).__aenter__(mgr) şeklinde bir mgr parametresi geçilse anlayabileceğim ama
async def __aenter__(self) olarak sınıf içinde tanımlanmış metoda nasıl parametre vermişiz gibi anlıyor bunu Python. Bir bit yeniği var ama çözemedim.

Hmm, şimdi anladım. Keşke daha basit bir örnek üzerinden sorsaydınız, sorunuzun bahsettiğiniz async/await konuyla ilgili olduğunu sandığım için anlamakta zorluk çektim. :slight_smile:

Şu örneği inceleyin, eğer sorunuz olursa da çekinmeyin:

>>> class A(object):
	def __init__(self):
		self.value = 5
	def yazdır(self):
		print(self.value)

		
>>> a = A()
>>> a.yazdır()
5
>>> A
<class '__main__.A'>
>>> type(a)
<class '__main__.A'>
>>> A == type(a)
True
>>> type(a).yazdır()
Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    type(a).yazdır()
TypeError: yazdır() missing 1 required positional argument: 'self'
>>> class B(object):
	def __init__(self):
		self.value = 10

		
>>> b = B()
>>> type(a).yazdır(b)
10

@ismailarilik hocam size nasıl teşekkür etsem bilemedim, çok ama çok teşekkürler, şu an gerçekten çok mutluyum :slight_smile:

1 Beğeni