Python Gelişmiş Programlama-Dekoratör Süper Ayrıntılı Açıklama

Gelişmiş Python Programlama-Dekoratör Süper Ayrıntılı Açıklama (Bölüm 1)

Seni dikkatlice gönder ve beni takip etmeyi unutma! !

Metni girin

Tam metin özeti

Dekoratör, python dilinin önemli bir özelliğidir.Nesne yönelimli tasarım veya ilgili kitaplıkların kullanımı olsun, genellikle bununla karşılaşıyoruz, ancak dekoratörlerin giriş ve çıkışları hakkında derinlemesine ayrıntılar sağlayan az sayıda makale var.Sonuç, birçok insanın bildiği Tabii nedenini bilmiyorum, bu yüzden Python dekoratörleri hakkında detaylı bir makale yayınlamayı planlıyorum.Yüksek içerik nedeniyle makale iki bölüme ayrılıyor, ilk bölüm bu yazıda anlatılacak. Çok dikkat! Makale çok uzun, tam metni okumak için yaklaşık 20 dakika.

Tam metin kataloğu

01 Python dekoratörünün doğumunun arka planı

1.1 Basit bir durumdan bahsetmek

1.2 "Dekoratör" olmayan ek işlevler eklemeyi gerçekleştirir

02 Dekoratör nedir

2.1 İki seviyeli dekoratör tanımı

2.2 Dekorasyonun rolü - iki yön

2.3 Dekoratörlerin senaryolarını kullanın

03 Dekoratörün uygulanması

3.1 Dekoratörlerin adım adım uygulanması

3.2 Dekoratörlerin genel "şablonu"

04 Dekoratörlerin sınıflandırmasının uygulanması (sonraki fragman)

Python dekoratörünün ayrıntılı açıklaması (bölüm 1)

01

Python dekoratörünün doğumunun arka planı

01 Dekoratörün doğumunun arka planı

1.1 Basit bir durumdan bahsetmek

Dekoratörün tanımı çok soyut ve farklı makalelerin farklı ifadeleri var ama başlangıçta size bir Python dekoratörünün ne olduğunu söylemeyeceğim, çok ani, küçük bir örnek alalım.

Önce basit bir işlevi tanımlayın:

def myfunc:

print ('Ben işlevimim')

myfunc () #Call işlevi

Sonra, bu fonksiyonun bu fonksiyonu çalıştırmasının ne kadar sürdüğünü görmek istiyorum, o zaman bunu yapabiliriz:

ithalat zamanı

def myfunc:

start = time.clock ()

print ('Ben işlevimim')

end = time.clock ()

print (f 'işlevi zaman alır: {end-start}')

myfunc () #Function çağrısı

Artık amacımıza ulaştık. Ama eğer öyleyse, aynı işlevi diğer bazı işlevler için uygulamaya devam etmek istiyoruz. Öyleyse bu birkaç cümleyi her bir işleve ekliyor muyuz? Elbette olabilir, ancak verimli ve zahmetli değil. Tüm sorunları bir defada çözmenin belli bir yolu varsa, doğal olarak en iyisidir, dolayısıyla "dekoratörler" ortaya çıkmıştır.

Yukarıdaki örnekte, işlevin kendisinin işlevi yalnızca bir cümleyi yazdırmaktır, ancak dönüştürülen işlev yalnızca bu cümleyi yazdırmakla kalmamalı, aynı zamanda işlevi yerine getirmek için gereken süreyi de görüntüleyebilmelidir; bu, bu işleve eklemeye eşdeğerdir. Ekstra özellikler , Bu anahtar kelimeye aslında " Dekoratör "İşleve ekstra özellikler eklemektir.

01 Dekoratörün doğumunun arka planı

1.2 "Dekoratör" olmayan ek işlevler eklemeyi gerçekleştirir

Unutmayın, bir işlev Python'da birinci sınıf bir yurttaştır, bu nedenle bir işlev zamanını yeniden tanımlamayı, işlevim referansını ona iletmeyi ve sonra işlevimi zamanında çağırmayı ve zamanlamayı düşünebiliriz, böylece işlevimde hiçbir değişiklik yapmamış oluruz. Kodun tanımlanması ancak ek fonksiyonların eklenmesinin amacı aşağıdaki gibidir:

ithalat zamanı

def myfunc ():

print ("Ben işlevimim")

def timeit (işlev):

start = time.clock ()

işlev ()

end = time.clock ()

print (f'Fonksiyonu çalıştırmak için geçen süre: {end-start} ')

timeit (işlevim)

Sonuç şu şekildedir:

Ben işlevim

İşlevi yürütmek için geçen süre: 0.0004924657368762765

Yukarıdaki kod mantıksal olarak sorun değil gibi görünüyor ve başarmak istediğimiz şeyi başardı! Ancak, işlevim işlevinin tanımındaki kodu değiştirmemiş olsak da, kodun çağıran kısmını değiştirmiş gibi görünüyoruz. Başlangıçta, bunu şöyle adlandırdık: myfunc (), değişiklikten sonra oldu: timeit (myfunc). Bu durumda, işlevim N yerde çağrılırsa, kodu bu N yerde değiştirmeniz gerekir. Ya da daha aşırı, bir yerde çağrılan kodun değiştirilemeyeceği durumu düşünün, örneğin: bu işlev başkalarının kullanması için verilmiştir.

Aslında, işlevi bir parametre olarak geçirmek zaten Dekoratörün prototipi Ancak yukarıdaki uygulama yeterince iyi değil, aşağıdakiler daha iyi bir uygulama sağlayacaktır.

02

Dekoratör-dekoratör nedir

02 Dekoratör nedir

2.1 Dekoratör iki seviyenin tanımı

Genel olarak, işleve bazı ek işlevler eklemem gerekirse, işlevin kaynak kodunu değiştirmem gerekir, ancak daha önce de belirtildiği gibi, çok zahmetli ve verimsizdir.Dekoratörler özel çözümdür!

Dekoratör tanımı esas olarak İki farklı seviye Göstermek için.

Python'da iki tanım düzeyi vardır:

Birincisi: Tasarım kalıpları kodunun yeniden kullanımı düzeyinden

Dekoratör, en boy gereksinimleri olan senaryolarda sıklıkla kullanılan, iyi bilinen bir tasarım modelidir.Daha klasik uygulamalar, günlükleri eklemeyi, performansı kontrol etmek için zamanlama mantığı eklemeyi ve işlem işlemeyi eklemeyi içerir. Dekoratör, bu tür problemleri çözmek için mükemmel bir tasarımdır, Dekoratörlerle, aynı kodun işleviyle hiçbir ilgisi olmayan çok sayıda işlevi çıkarabilir ve yeniden kullanmaya devam edebiliriz. . Özetle, bir dekoratörün rolü, mevcut bir nesneye ek işlevler eklemektir.

İkincisi: Python'un gramer seviyesinden (Aslında, ikinci tür esasen birinci türdür, ancak dilbilgisi açısından standartlaştırılmıştır)

Kısaca, python dekoratörü, orijinal fonksiyonun fonksiyonunu genişletmek için kullanılan bir fonksiyondur.Bu fonksiyonun özel özelliği, dönüş değerinin de bir fonksiyon olmasıdır.Python dekoratörünü kullanmanın avantajı, orijinal fonksiyonun kodunu değiştirmesine gerek olmamasıdır. İşleve yeni işlevler ekleyin. Bu şekilde, orijinal işlevin işlevini genişletmek istiyorsak, işlevdeki kaynak kodunu değiştirmemize gerek yoktur.

02 Dekoratör nedir

2.2 Dekoratörlerin rolü - iki düzey

Yukarıdaki ifadelerle, en temel iki sonuç çıkarılabilir.Aslında bunlar aynı zamanda dekoratörlerin en temel iki işlevidir:

(1) Aynı kodu çıkarın ve yeniden kullanın

(2) İşleve ek işlevler ekleyin

02 Dekoratör nedir

2.3 Dekoratörlerin senaryolarını kullanın

Dekoratörler her zamanki kodlamamızda daha az tanımlanabilir ve daha sık kullandığımız @staticmethod, @classmethod, @property vb. Gibi başkalarının önceden yazılmış dekoratörlerini daha sık kullanırız. Bunların hepsi diğerleridir. Bir kez yazıldıktan sonra, bunu kendimiz uygulamamıza gerek yoktur.Kodlamada, aşağıdaki durumlarda sıklıkla dekoratörlerle karşılaşacağız.

(1) Önbellek dekoratörü

(2) İzin doğrulama dekoratörü

(3) Zamanlama dekoratörü

(4) Günlük dekoratörü

(5) Rota dekoratörü

(6) İstisna işleme dekoratörü

(7) Dekoratör yeniden deneme hatası

Daha sonra, aslında python dekoratörleriyle ayrılmaz bir şekilde ilişkili olan python-python tanımlayıcısının (tanımlayıcı) gelişmiş gramerinden bahsedeceğim.Ayrıntılar için lütfen aşağıdaki makaleye bakın!

03

Dekoratörün uygulanması

03 Dekoratör uygulaması

3.1 Dekoratörlerin adım adım uygulanması

Yukarıdaki kodun geliştirilmiş sürümüyle ilgili sorunlar ışığında, çözümler bulduk:

N'de çağıran kodu değiştirmek çok zahmetli olduğu için, çağıran kodu değiştirmemenin bir yolunu bulacağız; eğer çağıran kod değiştirilmezse, bu, myfunc () çağrısının timeit (myfunc) çağrısı etkisine sahip olması gerektiği anlamına gelir.

Python'daki her şey bir nesne olduğu için, işlevime timeit atamayı düşünebiliriz,

ithalat zamanı

def myfunc ():

print ("Ben işlevimim")

def timeit (işlev):

start = time.clock ()

işlev ()

end = time.clock ()

print (f'Fonksiyonu çalıştırmak için geçen süre: {end-start} ')

myfunc = timeit #Assign timeit orijinal myfunc'a

işlevim ()

Ama yukarıdaki çağrı Başaramayacak , Aşağıdaki hata görüntülenecektir:

timeit () gerekli 1 konumsal bağımsız değişken eksik: 'işlev'

neden? Bunun nedeni, myfunc'a timeit atandıktan sonra, bu sefer myfunc ve timeit aynı şeyi temsil ediyor, ancak timeit'in bir parametre işlevi var gibi görünmesi ve myfunc () çağrılırken hiçbir parametre aktarılmamasıdır, bu yüzden başarılı olmaz. .

Ancak, yukarıdaki çağrı başarılı olmamasına rağmen, bize önemli bir ipucu verdi, çünkü yukarıdaki kod çözüldü " Çağrı kodunu değiştirin "Sorun, parametrelerin birleşik olmamasıdır, bu yüzden parametreleri birleştirmeye çalışın! Sonra başka bir işlev ekleyin! Ne demek istiyorsun?

Parametreler tek tip olmadığından, timeit () doğrudan ek işlevler eklemezse, myfunc parametre listesiyle tutarlı bir işlev döndürür. Görünüşe göre, ek işlev kodu eklemesi ve sonra zaman içinde bir işlev tanımlaması gerekiyor. Yapılabilir mi? Timeit'in (işlevim) dönüş değerini işlevim'e atayın. Ardından, myfunc () işlevini çağıran kodun hiç değiştirilmesine gerek kalmaz. . Yani, hala işlevim diyoruz (arama kodu değişmedi), ancak ek işlevler eklemenin etkisi de elde edildi!

kod aşağıdaki gibi gösterilir:

ithalat zamanı

#Original function myfunc

def myfunc ():

print ("Ben işlevimim")

# Bir zamanlayıcı tanımlayın

def timeit (işlev):

'' '

Timeit işlevi bir sarmalayıcıyı döndürmekten sorumludur ve sarmalayıcının parametreleri orijinal işlevim ile aynı olmalıdır.

Bu şekilde, myfunc = timeit (myfunc) myfunc'u yürütmek tamamen wrapper ile eşdeğerdir

Sarmalayıcı işlevi, ekstra özellikler eklemekten sorumludur

'' '

def sarmalayıcı ():

start = time.clock ()

işlev ()

end = time.clock ()

print (f'Fonksiyonu çalıştırmak için geçen süre: {end-start} ')

dönüş sarıcı

myfunc = timeit (myfunc) #Bunun önceki "myfunc = timeit" den farklı olduğuna dikkat edin

myfunc () #Bu hala orijinal myfunc () çağrısıyla aynıdır, ancak ek işlevler ekleme etkisine ulaşır

Yukarıdaki işlemin sonucu aşağıdaki gibidir:

Ben işlevim

İşlevi yürütmek için geçen süre: 0.0005973331798019136

sonuç olarak: Yukarıdaki işlev tanımında ve çağrısında, myfunc () çağrımın orijinalden farklı olmadığı görülüyor, ancak ek efektler eklenmiş. Önceki iki sorunu çözer:

(1) İşlevin kaynak kodunu veya işlevi çağıran kodu değiştirmeye gerek yoktur, orijinal myfunc () koduyla tamamen aynıdır, ancak ek işlevler eklenir;

(2) tutarsız timeit ve myfunc parametreleri sorununu çözün, yani başka bir sarmalayıcı katmanı ekleyin;

Bu dekoratör.

Yukarıdaki dekoratör orijinal versiyondur, ancak özel versiyondur " Sözdizimsel şeker "Dekoratörün daha profesyonel ve daha güzel görünmesi için uygulamak. Sadece karakterleri kullanın" @ "Başarmak için. Kod aşağıdaki gibidir:

ithalat zamanı

# Bir zamanlayıcı tanımlayın

def timeit (işlev):

'' '

Timeit işlevi bir sarmalayıcıyı döndürmekten sorumludur ve sarmalayıcının parametreleri orijinal işlevim ile aynı olmalıdır.

Bu şekilde, myfunc = timeit (myfunc) myfunc'u yürütmek tamamen wrapper ile eşdeğerdir

Sarmalayıcı işlevi, ekstra özellikler eklemekten sorumludur

'' '

def sarmalayıcı ():

start = time.clock ()

işlev ()

end = time.clock ()

print (f'Fonksiyonu çalıştırmak için geçen süre: {end-start} ')

dönüş sarıcı

# myfunc = timeit (myfunc) #Bunun önceki "myfunc = timeit" den farklı olduğuna dikkat edin

#Original function myfunc

@timeit

def myfunc ():

print ("Ben işlevimim")

myfunc () #Bu hala orijinal myfunc () çağrısıyla aynıdır, ancak ek işlevler ekleme etkisine ulaşır

Yukarıdaki kodun sonucu hala:

Ben işlevim

İşlevi yürütmek için geçen süre: 0.0004893814003196401

Yukarıdaki örnekte, @timeit, önceki yazım myfunc = timeit (myfunc) ile tamamen eşdeğer olan myfunc fonksiyonunun tanımının üzerine eklenmiştir,

@ İki önemli işlevi vardır ,

ilk: Daha az kod yazma;

ikinci: Bu, kodumuzun daha süslü ve daha yüksek kaliteli görünmesini sağlamaktır.

sonuç olarak

Bu örnekte, fonksiyon girerken ve çıkarken zamanlama gerektirir. Buna a Kesit (Açı) , Bu programlama yöntemine Görünüşe Dayalı Programlama (Görünüşe Yönelik Programlama) . Geleneksel programlama alışkanlıklarının yukarıdan aşağıya yürütme yöntemi ile karşılaştırıldığında, işlev yürütme sürecindeki gibidir. Yatay olarak bir mantık parçası ekle . Belirli bir iş alanında, çok sayıda kod tekrarını azaltabilir. Bakış açısına yönelik programlamada hala epeyce terim var, bu yüzden burada daha fazlasını tanıtmayacağım. İlgileniyorsanız, ilgili bilgileri bulabilirsiniz (gerekirse, daha sonra bakış açısına yönelik programlama üzerine bir dizi makale yazmak için de zaman ayıracağım, bkz. Vaktim var mı!)

03 Dekoratör uygulaması

3.2 Dekoratörlerin genel "şablonu"

Dekoratörün uygulama prensibini netleştirebilmek için, işte dekoratörün açıklaması "Genel şablon "Herkesin anlaması kolaydır! Ancak, bir tasarım modeli olarak, dekoratörün kendisi sabit bir tasarım şablonuna sahip değildir ve sözdizimi nispeten esnektir. Nasıl doğru yazılacağı söylenmez.

Şablon aşağıdaki gibidir:

def dekoratör (işlev):

'' '

İlk katman işlevi, dekoratör adıdır

işlev: parametre, yani dekore edilecek işlev

dönüş: orijinal fonksiyon parametreleriyle tutarlılık sağlamak için dönüş değeri sarmalayıcısı

'' '

def sarmalayıcı (* arg, ** değiştirgeler):

'' '

İç işlev, bu işlev "ekstra özellikler ekleme" görevini yerine getirir

* arg, ** args: Parametreler, dekore edilmesi gereken fonksiyon parametreleriyle tutarlı tutulur. Burada, bunun yerine * arg ve ** args kullanılır

'' '

# İşte ekstra fonksiyon kodu

function () #Orijinal işlevi çalıştır

# İşte ekstra fonksiyon kodu

dönüş sarıcı

Genellikle, yukarıdaki şablona göre "dekoratör" işlevini yazmanız yeterlidir ve hata olmayacaktır.

Önlemler:

(1) Dekoratör genellikle iki işlev katmanından oluşur; dış dekoratör ve iç sarıcı;

(2) Parametreleri orijinal işlevle tutarlı tutmak için birinci katman işlevinin parametre işlevi, yani dekore edilmesi gereken işlev ve dönüş değeri sarmalayıcısı

(3) İç işlev, bu işlev "ekstra özellikler ekleme", * arg, ** args görevini yerine getirir: Parametreler, dekore edilmesi gereken işlev parametreleriyle tutarlı tutulur, burada * arg ve ** args ile değiştirilir.

04

Dekoratörlerin çeşitli süslü uygulamaları

04 Dekoratörlerin çeşitli süslü uygulamaları

4.1 Dekoratörlerin türe göre uygulanması

Dekoratörleri öğrenen herkes Python'u bilir Kapanış "Kapanış" ın ayrıntılı tanımının çeşitli versiyonları vardır, ancak sık sık böyle bir cümle görüyoruz, "Python dekoratörü bir tür kapatmadır veya Python kapatması aslında dekoratördür", bu cümle bir dereceye kadar Yukarıdakiler yanlıştır, ancak bunu söylemekte sorun yoktur (kalbinizdeki ikisinin doğasını anlayın).

Doğa: Python kapanışları, dekoratörlerin gerçek bir alt kümesidir, yani dekoratörler daha geniş bir kavramdır, neden ikisi arasındaki fark ve bağlantıya gelince, bir sonraki makalede ayrıntılı olarak açıklayacağım. Sonraki makale için referans:

Gelişmiş Python Programlama-Dekoratör Ayrıntılı Açıklama (Bölüm 2)

Sadece bu değil, yukarıda uygulanan dekoratörler işlevler içindir.Aslında, Python dekoratörleri "işlevler" veya "sınıflar" olabilir ve dekore edilmiş nesneler "işlevler" veya "sınıflar" da olabilir. Dört eşleştirme durumu vardır:

İşlev dekorasyon işlevi

İşlev dekorasyon sınıfı

Sınıf dekorasyon işlevi

Sınıf dekorasyonu

Her biri ayrıntılı olarak nasıl uygulanır? Aslında tasarım fikirleri birbirine benziyor ama uygulama detayları biraz farklı, detayları öğrenmek istiyorsanız bir dahaki sefere dinleyin! ! !

Bir sonraki uyarı:

Dekoratörler ve kapanışlar arasındaki bağlantı ve fark

Dört tip dekoratörün eşleştirilmesinin gerçekleştirilmesi

····

Python tarafından kullanılan üç e-kitap bu makalenin ilerleyen bölümlerinde paylaşılacaktır. Bunları nasıl elde edeceğiniz: iletilen makaleyi takip edin, özel mektup editörü (öğrenin)

"Python Röportaj Koleksiyonu" "Python Çekirdek Programlama Üçüncü Sürüm" "Veri Analizi İkinci Sürüm için Python Kullanın"

Elde etme yöntemi: Yönlendirme makalesi özel mektup düzenleyicisini izleyin (öğrenme)

İlk yarı-Viyana hızlı bir şekilde 0-1 Inter, Lautaro gol attı
önceki
Samimiyetle dolu, e-spor seçenekleri, kutudan çıkar çıkmaz HyperX Aloi yeşil eksenli mekanik klavye
Sonraki
Python gelişmiş seri 02 nesnelerin derin kopyası (derin kopya ve gölge kopya)
Retro ve havalı, nostaljik ve klasik, Baweitang klasik Bluetooth hoparlör deneyimi
Python gelişmiş hata ayıklama becerileri (iki) IPython hata ayıklama becerileri (öğrenme yolları ve PDF dahil)
Küçük boyutlu ve mükemmel işçilik, bu Baweitang klasik Bluetooth hoparlörü çok bireysel
İlk yarı-Borisov 1-0 Arsenal, Dragon skorları
599.000'den başlayan 2019 BMW 6 Serisi GT satışa çıktı, tüm seriler fiyatları düşürdü ve 3.0T gücü iptal etti
Tüm yönleri dinleyin, Logitech G233 oyun kulaklığı deneyimi
Çocukluk anılarını geri getirin! Baweitang Klasik Bluetooth Hoparlör Deneyimi
Tarayabilir misin? Hayır, QR koduyla oynamak farklı olacak
Python coroutine serisi (6) asyncio + tkinter geliştirme
California Fire Bull vahşileşiyor! Red Fire Bull CR1280 PRISM Full Tower RGB Oyun Kasası Derin Araştırma
Python coroutine serisi (6) -EventLoop ve Future ayrıntılı açıklama ve eşzamanlılık gerçekleştirme
To Top