Bekarlar Günü yakında geliyor Size bir Python nesnesi tanıtmak ister misiniz? | CSDN blog seçimi

Yazar | Tianyuan Prodigal Son

Editör | Liu Jing

Üretildi | CSDN Blogu

Önsöz

Bekarlar Günü yaklaşıyor İnsanları tanıtmaya gelince, sanırım Uncle Passion'un evinden Bayan Sınıfı (sınıf) ve Küçük Kardeş (def) düşünmüşsünüzdür. Başını belaya sokma, ciddi ol! Bugünkü konumuz erkek ve kadın arkadaşları tanıtmak değil, programcıların genellikle OOP dediği nesne yönelimli programlamanın nasıl yapılacağını açıklamaktır.

Öncüllerin Nesne Yönelimli Programlamayı neden nesne yönelimli programlamaya dönüştürdüklerini bilmiyorum, bu yüzden tek programcılar genellikle ekrandaki yakışıklı adamların ve güzelliklerin gelecekte karşılaşacakları nesneler olduğu yanılsamasına kapılırlar. Bunu söyledikten sonra, bilgisayar terminolojisinin Tayvan'daki meslektaşlarından çevrilmesinin daha uygun olduğunu düşünüyorum. Örneğin önbellek, biz ona "önbellek" diyoruz, diğerleri ise "önbellek", kulağa hoş geliyor. Tayvanlı meslektaşları, OPP'yi "nesne yönelimli programlama" olarak tercüme eder - eşit derecede açık olmasa da, en azından tek programcıların "nesnelere" sahip olmama zahmetini geçici olarak unutmasına neden olabilir.

Biraz tuz, bu blogcu resmi olarak nesneleri herkes için tanıtmaya başladı.

Sınıflar ve nesneler kavramı

Nesneye yönelik programlamayı öğrenmek için önce nesnenin ne olduğunu anlamalısınız? Sınıf nedir? Örnekleme ne anlama geliyor? Aşağıdaki şekil, OOP'nin bu temel kavramlarını anladığımı ifade ediyor (aslında uzlaşmanın sonucudur - bunu meslektaşlarımla uzun süre tartıştım ve duvardan Wikipedia'ya atıfta bulundum).

Sınıf, uğraşmak istediğimiz nesnel şeylerin bir soyutlamasıdır. Bir sınıf, aynı özelliklere ve yöntemlere sahip bir nesne koleksiyonunu tanımlamak için kullanılır ve koleksiyondaki her nesne için ortak olan özellikleri ve yöntemleri tanımlar. Bir nesne, bellekteki bir sınıfın bir örneğidir ve bir sınıf, birden çok nesneye örneklenebilir. Sınıflar soyuttur ve hafızayı almazken, nesneler somuttur ve depolama alanı kaplar.

Sınıf üyesi

Python'a yeni başlayan biri olarak, enerjinizi şaşırtıcı kavramlara harcamanıza gerek yoktur, yalnızca sınıfları kullanmanın temel öğelerinde ustalaşmanız gerekir. Önümüzdeki günlerde, OOP'nin derinliğini yavaş yavaş takdir etmek için yeterli zamanınız olacak. Tecrübe birikimi ile OOP doğal olarak düşünme aracınız haline gelecektir.

Aşağıdaki kod, A adlı bir sınıfı tanımlar. Tüm sınıfların kurucuları ve yıkıcıları vardır.Ayrıca üye işlevler ve üye değişkenler de içerebilirler. Üye işlevlere bir sınıfın yöntemi ve üye değişkenleri bir sınıfın özellikleri olarak çağırmayı seviyorum.

a sınıfı: def __init __ (öz): "" "Yapıcı" "" self.a = 10 # bir üye değişkeni a tanımlar def getA (öz): "" "Üye İşlevi" "" baskı ("a =% d"% self.a) def __del__: "" "Yıkıcı" "" print ("nesneyi sil") a = A a.getA

Bir sınıf bir nesne olarak somutlaştırıldığında, önce kurucu çalıştırılır ve nesne yok edildiğinde, yıkıcı otomatik olarak çalıştırılır. Genel olarak, yapıcıda başlatma çalışması yapacağız ve yıkıcıda temizleme işi yapacağız.

Bunu okuduktan sonra, birçok yeni başlayan kesinlikle şunu söyleyecektir: Bir sınıfı tanımladığımda, bir kurucu yazdım ama asla bir yıkıcı yazmadım Neden tüm sınıfların bir kurucusu ve bir yıkıcısı olduğunu söylüyorsunuz? Bu doğru, bir sınıfı tanımlarken, bir kurucu ve bir yıkıcı yazmasak bile, bu iki yöntem hala mevcuttur (yıkıcı biraz özeldir ve onu doğrudan göremeyiz - kendimiz tanımlamadığımız sürece). Yapıcı ve yıkıcıyı kendimiz tanımlarsak, sistem tarafından otomatik olarak atanan iki işlevi değiştirecektir. Aşağıdaki örnek, gizemi açıkça göstermektedir: A Sınıfının ne kurucusu ne de yıkıcısı vardır ve B sınıfının yalnızca bir yıkıcısı vardır. Her iki sınıf da sınıf örnekleri oluşturabilir veya her ikisi de yok edilebilir ve önce b Özel bir yıkıcı denir.

> > > a sınıfı: geçmek > > > a = A > > > del a > > > a Geri izleme (en son çağrı son): Dosya " < Pyshell # 70 > ", 1. satır, içinde < modül > a NameError: name'a 'tanımlı değil > > > B sınıfı: def __del__ (öz) : print ('Yıkıcıyı çalıştır, sahneyi temizle') > > > b = B > > > del b Yıkıcıyı yürüt, sahneyi temizle > > > b Geri izleme (en son çağrı son): Dosya " < Pyshell # 75 > ", 1. satır, içinde < modül > b NameError: name'b 'tanımlı değil

Yeni tarz ve eski tarz

PY2'de yeni stil ve eski stil olmak üzere iki tür sınıf vardır. Yeni stil sınıfın, sanal sınıf Object'ten miras alması gerekirken, eski stil sınıfın bunu yapmaması gerekir. PY2'de sınıf yazmanın üç yolu vardır:

A sınıfı (nesne): yeni stil sınıf yazma A sınıfı: Eski stil sınıf yazısı A sınıfı: Eski stil sınıf yazısı

PY3'te yalnızca yeni tarz sınıflar vardır ve eski tarz sınıflar artık desteklenmemektedir. Nesne yazısını miras almaya alışkınsanız, hiçbir sorun yoktur. Yukarıdaki üç yazma yönteminin tümü PY3'te yeni stil sınıfları olarak yorumlanır. Yeni tarz ile eski tarz arasındaki temel farklar şunlardır:

  • Yeni stil sınıf, Object yapıcısını ve yıkıcısını miras alabilir.Sınıfın yapıcısı ve yıkıcısının özel bir işi yoksa, bunlar çıkarılabilir. Eski tarz sınıf şunları yapamaz:

a sınıfı: def print (kendi kendine): baskı ("Ben A") B (A) sınıfı: def __init __ (öz): A .__ init __ (kendi) b = B

Şu anda PY2 ile çalışırken bir hata oluşacaktır: AttributeError: A sınıfının '__ init__' niteliği yoktur, PY3 kullanılırken bu hata oluşmaz. Yeni bir yazı türüne değiştirilirse:

A sınıfı (nesne): def print (kendi kendine): baskı ("Ben A") B (A) sınıfı: def __init __ (öz): A .__ init __ (kendi) b = B

Hala PY2 ile çalışıyor, hiçbir hata olmayacak.

  • Yeni stil sınıflar süper kullanabilir:

A sınıfı (nesne): def baskı (öz) : baskı ("Ben A") B (A) sınıfı: def __init__ (öz) : super (A, self) .__ init__ b = B
  • Çoklu kalıtımda, her bir ana sınıfın başlatma ve işlev arama sırası farklıdır: eski tarz sınıf derinlik öncelikli kalıtımdır ve yeni tarz sınıf, en önce kalıtımdır.

Statik değişkenler ve örnek değişkenler

Yapıcıda tanımlanan değişkenlere örnek değişkenler denir. Örnek değişkenleri yalnızca somutlaştırmadan sonra kullanılabilir < Nesne adı Değişken adı > Erişim yolu. Statik değişkenler genellikle yapıcıdan bağımsız olarak sınıfın başında tanımlanır. Statik değişkenler olabilir < Nesne adı Değişken adı > Erişim yolu, şunları da yapabilirsiniz: < Sınıf adı Değişken adı > Erişim yolu. Genel olarak, bir sınıfın statik değişkenleri, genellikle sınıfın yöntemleri tarafından kullanılabilen ancak sınıfın yöntemleriyle değiştirilmemesi gereken statik özelliklerini depolamak için kullanılır.

> > > a sınıfı: static_x = 10 # Statik değişken def __init__ (öz) : self.instance_y = 5 # örnek değişkeni > > > a = A > > > a.static_x 10 > > > a.instance_y 5 > > > A.static_x 10 > > > A.instance_y Geri izleme (en son çağrı son): Dosya " < Pyshell # 89 > ", 1. satır, içinde < modül > A.instance_y AttributeError: tür nesnesi '' duruş_y 'özniteliğine sahip değil

Statik fonksiyon

Diğer seslerin statik işlevlerinden farklı olarak, her ikisi de dekoratörlerle gerçekleştirilen Python'un iki statik işlevi vardır:

a sınıfı: static_x = 10 def __init__ (öz) : self.y = 10 @hayalhanemersin def staticFuc: baskı (A.static_x) @sınıf def classFuc (cls) : baskı (cls.static_x) A.staticFuc A.classFuc

Staticmethod işlevi Self parametresini kullanamaz, bu nedenle herhangi bir üye değişkenine erişemez ve yalnızca sınıf adı aracılığıyla sınıfın statik değişkenlerine erişebilir.

Classmethod işlevi de Self parametresini kullanamaz, bu nedenle herhangi bir üye değişkenine erişemez, ancak bir cls parametresine sahiptir. Cls parametresi, bir nesneye bir başvuru değildir, ancak sınıfa bir başvurudur ve sınıfın statik değişkenlerine cls parametresi aracılığıyla erişilebilir.

Nesneye yönelik üç öğe

Nesne yönelimli üç öğeye sahiptir: kalıtım, kapsülleme ve çok biçimlilik. Burada çok fazla kavram var ve bunun hakkında ne kadar çok konuşursanız o kadar kafası karışıyor. Okuyucuyu yanıltmamak için elimden geldiğince açıklamamaya çalışıyorum ve sadece örnekler veriyorum, lütfen kendiniz deneyin.

(1) Kalıtım

Türetilmiş sınıfın yalnızca bir ana sınıfı varsa, bu tek kalıtımdır. Bu, sınıf tanımının en yaygın biçimidir.

sınıf Hayvan: yenilgi (öz) : print ('yiyebilirim') Sınıf Brid (Hayvan): def __init__ (öz) : Animal .__ init __ (kendi) def uçmak (öz) : print ('Uçabilirim') brid = Brid brid.eat brid.fly

Türetilmiş sınıfın birden çok üst sınıfı varsa, bu çoklu mirastır.

sınıf Geyik: def showHorns (öz) : print ('boynuzlarım var') sınıf At: def showFace (öz) : baskı ('At yüzüm var') inek sınıfı: def showHoof (öz) : baskı ('toynaklarım var') sınıf Eşek: def showTail (öz) : baskı ('Eşek kuyruğum var') Sınıf Milu (Geyik, At, İnek, Eşek): # Çoklu miras, dört farklı sınıftan türemiştir. def __init__ (öz) : Deer .__ init __ (kendi) Horse .__ init __ (kendi) İnek .__ init __ (kendi) Eşek .__ init __ (kendi) milu = Milu milu.showHorns milu.showFace milu.showHoof milu.showTail

İster tekli kalıtım isterse çoklu kalıtım olsun, türetilmiş sınıftaki üst sınıfın işlevini geçersiz kılabilirsiniz - buna kapsam denir.

(2) Paket

Sözde kapsülleme, sınıfın üye değişkenlerini ve üye işlevlerini entegre etmek ve anahtar bilgisini korumak veya gizlemektir. Üç bilgi koruma veya gizleme düzeyi vardır: genel, korumalı ve özel. C ++ deneyiminiz varsa, önce C ++ bilgi gizleme kurallarını gözden geçirelim:

  • Genel üyeler: sınıf dışındaki herhangi bir kod tarafından görülebilir;

  • Korumalı üyeler: sınıf dışındaki herhangi bir koda görünmez, ancak türetilmiş sınıflar tarafından görülebilir;

  • Özel üyeler: Sınıfın dışına ve türetilmiş sınıflara görünmez.

  • Bu üç seviyeye karşılık gelen Python şu şekilde tanımlanır:

  • İngilizce harflerle başlayan üyeler halka açık üyelerdir

  • Alt çizgiyle başlayan üyeler korumalı üyelerdir

  • İki alt çizgi anahtarı olan üyeler özel üyelerdir

  • Python'un bilgi korumasının veya gizleme kurallarının etkili olup olmadığını görmeye çalışalım.

    > > > A sınıfı (nesne): def __init__ (öz, a, b, c) : self.a = 10 # public self._b = b # koruma self .__ c = c # özel def getA (öz) : # Halka açık kendine dön. a def setA (öz, a) : # Halka açık self.a = a def getB (öz) : # Halka açık kendine dön._b def _setB (kendisi, b) : # Koruma self._b = b def getC (öz) : # Halka açık self .__ c def __setC (kendisi, c) : # Özel self .__ c = c > > > a = A (10, 20, 30) > > > B (A) sınıfı: geçmek > > > b = B (10, 20, 30)

    Genel üyelere erişmeye çalışın:

    > > > a.a 10 > > > a.getA 10 > > > a.setA (5) > > > a.a 5 > > > b.a 10 > > > b.getA 10 > > > b. setA (5) > > > b.a 5

    Genel üyeler için erişim kuralları C ++ ile aynıdır. Önce korunan üyeleri atlayın ve özel üyelere bakın:

    > > > AC Geri izleme (en son çağrı son): Dosya " < küçük resim # 85 > ", 1. satır, içinde < modül > AC AttributeError: 'Bir' nesnesinin '__ c' özniteliği yok > > > a.getC 30 > > > a .__ setC (5) Geri izleme (en son çağrı son): Dosya " < Pyshell # 87 > ", 1. satır, içinde < modül > a .__ setC (5) AttributeError: 'Bir' nesnesinin '__ setC' niteliği yok > > > M.Ö Geri izleme (en son çağrı son): Dosya " < pijama # 88 > ", 1. satır, içinde < modül > M.Ö AttributeError: 'B' nesnesinin '__ c' niteliği yok > > > b.getC 30 > > > b .__ setC Geri izleme (en son çağrı son): Dosya " < Pyshell # 90 > ", 1. satır, içinde < modül > b .__ setC AttributeError: 'B' nesnesinin '__ setC' niteliği yok

    Özel üyeler için erişim kuralları da C ++ ile aynıdır. Öyleyse neden üyeleri korumayı atladım? Dene:

    > > > a._b 20 > > > a._setB (5) > > > a._b 5

    Bunu görmek doğru değil, sadece sınıfın içindeki kod ve türetilmiş sınıflar kullanılabilir.Doğrudan nasıl kullanılabilir? Evet, Python'un korumalı üye erişim kuralları gerçekten C ++ 'lardan farklıdır. Python'un korunan üyelerinin mekanizması nedir? Python'un OOP'sinde üyeleri korumakla kamu üyeleri arasında hiçbir fark olmadığı ortaya çıktı. Koruma kuralı yalnızca xxx içe aktarım * için geçerlidir.

    testA.py

    A sınıfı (nesne): geçmek sınıf _B (nesne): geçmek

    testB.py

    testA içe aktarımından * a = A b = _B

    TestB.py yürütülürken:

    Geri izleme (en son çağrı son): "TestB.py" dosyası, satır 4, içinde < modül > b = _B NameError: name'_B 'tanımlı değil

    Şu anda, koruma üyesi _B korunmaktadır. Ancak bu durum yalnızca xxx'den içe aktarma * için geçerlidir. TestB.py böyle yazıyorsa:

    testB.py

    testA'dan içe aktarma A, _B a = A b = _B

    veya:

    ithalat testiA a = testA.A b = testA._B

    Sorun yok.

    (3) Polimorfizm

    Ana sınıf birden fazla türetilmiş sınıfa sahip olduğunda ve türetilmiş sınıfların tümü aynı üye işlevini uyguladığında, polimorfizm elde edilebilir:

    H2O sınıfı (nesne): def ne (öz): baskı ("Ben H2O'yum") Sınıf Su (H2O): def ne (öz): baskı ("Ben suyum") Sınıf Buz (H2O): def ne (öz): baskı ("Ben buzum") Sınıf Su Buharı (H2O): def ne (öz): print ("Ben su buharıyım"); def ne (obj): obj.what objs = obj içindeki obj için: ne (obj)

    Soyut sınıf

    Soyut sınıflar somutlaştırılamaz, yalnızca diğer sınıflar tarafından bir ana sınıf olarak miras alınabilir ve türetilmiş sınıfların soyut sınıftaki tüm üye işlevleri uygulaması gerekir. Soyut uygulama senaryosu nedir? Veri indirmek için birçok komut dosyası eklentisi yaptım. Farklı veri kaynakları farklı komut dosyaları kullanır. Tüm bu komut dosyaları aynı ada sahip yöntemler gerektirir. Şu anda soyut sınıflar kullanışlı oluyor.

    > > > abc içe aktar > > > A sınıfı (nesne, metasınıf = abc.ABCMeta): @ abc.abstractmethod def a (öz): geçmek @ abc.abstractmethod def b (öz): geçmek > > > C sınıfı (A): def a (öz): baskı ("a") > > > c = C Geri izleme (en son çağrı son): Dosya " < Pyshell # 127 > ", 1. satır, içinde < modül > c = C TypeError: Soyut yöntemler b ile soyut C sınıfı başlatılamıyor

    Tekli mod

    Singleton Pattern (Singleton Pattern) yaygın olarak kullanılan bir yazılım tasarım modelidir.Bu modelin temel amacı, belirli bir sınıfın yalnızca bir örneğinin var olmasını sağlamaktır. Tüm sistemde belirli bir sınıfın yalnızca bir örneğine sahip olmak istediğinizde (bir yazılım yapılandırma sınıfı gibi, yazılımda nerede somutlaştırılmış olursa olsun, her zaman bu tek nesne olacaktır), tekil desen kullanışlı olabilir. Örneğin, Python günlük modülündeki günlük nesnesi veya zaman uyumsuz iletişim çerçevesi Twisted'daki reaktörün tümü tipik tekil modellerdir - ancak aşağıdaki şekilde uygulanmaları gerekmez.

    Python, dekoratörleri kullanarak tekli kalıbı kullanabilir:

    def Singleton (cls): _instance = {} def _singleton (* args, ** kargs): cls _instance içinde değilse: _instance = cls (* args, ** kargs) return _instance dönüş _singleton @Hayalhanemersin sınıf Yapılandırması (nesne): geçmek cfg1 = Yapılandırma cfg2 = Yapılandırma baskı (cfg1, cfg2'dir)

    postscript

    Şimdiye kadar birkaç konuya değinelim. CSDN bize sadece böyle bir iletişim platformu sağlamakla kalmaz, aynı zamanda sık sık çeşitli teknik değişim faaliyetleri başlatır. Yakın gelecekte, Python acemileriyle GeekTalk sütununda nasıl hızla sağlam ve güçlü bir programcı haline gelebileceğimizi tartışacağım. CSDN ayrıca bu etkinlik için bazı hediyelik eşyalar da sağladı. Eğer ilgileniyorsanız, lütfen katılmak için kodu tarayın:

    Telif hakkı bildirimi: Bu makale, CSDN blog yazarı "Tianyuan Prodigal Son" un orijinal makalesidir.

    SON

    KDJ Golden Cha + BOLL ikinci kez orta pistte toparlandı: Bu tür bir hisse senedi satmayın, ana gücün yükselmesini bekleyin ve elinizde var mı bir bakın
    önceki
    Maliye Bölümü'nün kadın profesörü nadiren konuşuyor: Ana yıkama tablasının bu önemli hareketli ortalaması neden altına düşmüyor? "Hareketli ortalamaya geri dönmenin" ana cazibe geri sayımı olduğu ort
    Sonraki
    Orada mısın? Bir bina inşa etmeme yardım et
    Eğlenceli başlıklar dibe batıyor
    78 milyondan 900.000'e nasıl çıktım, sırf sürekli olarak "beş katmanın üzerinde satın al, üçüncü katmanın altında sat" yaptığım için, neredeyse tüm kısa vadeli kazançları tüketiyorum
    180 milyon hissedar karanlıkta: Neden "büyük hacim kutudan çıkıp" tamamen düşüyor? Bu makale paha biçilemez, 10 kez okudum, çok keskin ve kapsamlı
    Jack Ma parayla ilgilenmediğinden bahsedecek; Bill Gates: Microsoft Android'i yenebilirdi! TypeScript 3.7 yayınlandı | inek başlıkları
    anlaştık mı! Çin ve Fransa, Çinli uzmanların Notre Dame de Paris'in restorasyonuna katılacağı konusunda fikir birliğine vardı
    Wall Street avcıları nadiren konuşurlar: 10 yıl önce 48 yuan PetroChina satın aldılar ve şimdi sadece sorunu çözmekle kalmadı, aynı zamanda ikiye katladı. Hangi yönteme dayanıyor? Toplamaya değer
    Küçük fonlarla büyümenin en bilimsel yolu olan "MACD üç eksenli" ezberleyerek 3 yılda 50.000'den 7.8 milyona çıktım
    Tekvando, "Kuşak ve Yol" Çin Açık'ta Xi'an'a yardım etti
    MACD ve KDJ göstergeleri gibi gösterişli göstergelerden vazgeçin Bu göstergelerin gerçek kralı, özel sermaye ve sıcak para gizlice kullanılıyor.
    Günlük limit hisse senetlerini yakalamak için neredeyse her gün "çağrı teklifi% 5 daha yüksek açıldı" hilesi hatırladığım için 3,2 milyon kaybetmekten 8,9 milyon kazanmaya gitmem 5 yılımı aldı.
    Size söyleyeyim: Neden hisse senedinin önceki gün günlük limiti varken ertesi gün daha yüksek açılıştan sonra tekrar düştü? Son olarak, kapsamlı bir makale var, o zamandan beri onu gerçek formda satı
    To Top