Python面向對象總結及類與正則表達式

来源:https://www.cnblogs.com/moyulin/archive/2019/04/17/Yulinmo_0219.html
-Advertisement-
Play Games

Python3 面向對象 一丶面向對象技術簡介 類(Class): 用來描述具有相同的屬性和方法的對象的集合。它定義了該集合中每個對象所共有的屬性和方法。對象是類的實例。 方法:類中定義的函數。 類變數:類變數在整個實例化的對象中是公用的。類變數定義在類中且在函數體之外。類變數通常不作為實例變數使用 ...


Python3 面向對象


一丶面向對象技術簡介

  • 類(Class): 用來描述具有相同的屬性和方法的對象的集合。它定義了該集合中每個對象所共有的屬性和方法。對象是類的實例。
  • 方法:類中定義的函數。
  • 類變數:類變數在整個實例化的對象中是公用的。類變數定義在類中且在函數體之外。類變數通常不作為實例變數使用。
  • 數據成員:類變數或者實例變數用於處理類及其實例對象的相關的數據。
  • 方法重寫:如果從父類繼承的方法不能滿足子類的需求,可以對其進行改寫,這個過程叫方法的覆蓋(override),也稱為方法的重寫。
  • 局部變數:定義在方法中的變數,只作用於當前實例的類。
  • 實例變數:在類的聲明中,屬性是用變數來表示的。這種變數就稱為實例變數,是在類聲明的內部但是在類的其他成員方法之外聲明的。
  • 繼承:即一個派生類(derived class)繼承基類(base class)的欄位和方法。繼承也允許把一個派生類的對象作為一個基類對象對待。例如,有這樣一個設計:一個Dog類型的對象派生自Animal類,這是模擬"是一個(is-a)"關係(例圖,Dog是一個Animal)。
  • 實例化:創建一個類的實例,類的具體對象。
  • 對象:通過類定義的數據結構實例。對象包括兩個數據成員(類變數和實例變數)和方法。

和其它編程語言相比,Python 在儘可能不增加新的語法和語義的情況下加入了類機制。

Python中的類提供了面向對象編程的所有基本功能:類的繼承機制允許多個基類,派生類可以覆蓋基類中的任何方法,方法中可以調用基類中的同名方法。

對象可以包含任意數量和類型的數據。

1.類中帶下劃線開頭的變數特點

     類中的方法,其實就是類中的函數,可以分為:實例方法,類方法,靜態方法。方法和欄位一樣,也是屬於類的屬性,所以也具有運行中修改的特效, 但一般不推薦這樣做。

  我在類的基本語法中,介紹了構造器方法:__init__ 、__new__;解構器方法:__del__;

  註意,這裡雖然是以兩個下劃線(__)開頭,但同時以兩個下劃線(__)結尾,這裡表明其是一個‘魔法方法’,關於類中的魔法方法,將起一篇進行說明。

  但是,如果單純只以兩個下劃線開始,則依然是私有化的意思,看代碼示例:

複製代碼
class Test(object):

    def __scolia__(self):   # 一個類似魔術方法,並不是私有化
        return 'scolia'

    def __good(self):   # 私有方法
        return 'good'

a = Test()
print a.__scolia__()   # 魔法方法可以在直接訪問
print a.__good()    # 私有方法不能直接訪問
複製代碼

 

  同樣的,和欄位私有化一樣,我們也可能同特殊手段進行強制訪問:

print a._Test__good()  # 強制訪問

 

  當然,私有方法也可以在類的內部訪問,和私有欄位一樣。

  所以說,屬性的私有化都是對訪問入口進行混淆,同樣的,也不建議強制訪問私有屬性。

  也許這裡的‘魔法方法’看起來並不‘魔法’,詳情將以後解釋。


實例方法:

  在 __init__ 構造器中,提起過其是一個實例方法,實例方法的特點就是:

  1.方法的第一個參數必須是 self,當然這是約定俗成的寫法,你可以將 self 換成 abc 之類的,但是為了別的程式員能看得懂,還是統一用 self 吧。這裡的 self 代表實例本身,也就是說如果我實例化時使用的是: a = Test() ,那麼 self 就代表 a 這個實例,我們可以在很多構造器中看到類似 self.scolia = 'good' 的寫法,其實這個寫法和在類外面 a.scolia = 'good' 效果一樣,是為了添加屬性,只不過 __init__ 方法是實例化時自動調用的函數,所以適合進行初始屬性的創建。

  2.實例方法在調用的時候,self 是自動傳遞的,所以不需要我們再處理。

  3.實例方法一般要有實例才能調用,當然也有特殊的調用方法。

代碼示例:

複製代碼
class Test(object):

    def __init__(self, a, b):   # 構造器在實例創建時進行屬性的初始化
        self.a = int(a)
        self.b = int(b)

    def abc(self, c):  # 實例方法
        print self.a + self.b + int(c)  # 因為self是自動傳遞的,所以我們可以在實例方法中調用實例的屬性

a = Test(123, 321)  # 我們只要為 a 和 b 傳參就行了
a.abc(666)  # 同樣的,只要為 c 傳參
複製代碼

 

  這裡,將引入一個綁定 (binding) 的概念,其主要和方法的調用有關。

  首先,我們知道方法是類的屬性,而不是實例的屬性,在上篇博文類的屬性和實例的屬性中我們也討論過這個問題。

  其次,方法只有在其所屬的類擁有實例時,才能被調用。當一個類存在實例後,方法才被認為是綁定到這個實例。沒有實例的時候,方法是未綁定的。

  最後,任何一個方法定義的第一個參數都是變數 self ,它表示調用此方法的實例對象。

  很明顯這裡的綁定針對的是實例方法。因為如果沒有實例的話,self 就無法傳遞,這將導致參數的不足,當然就無法調用了。

  但是,我們可以自己傳遞 self 來調用未綁定的方法。調用未綁定的方法通常是在我們繼承了一個父類後, 我們覆蓋了父類中的某個方法,但是為了實現代碼重用,我們又想在子類中調用父類的方法。單純的複製父類中的代碼明顯不是一個好選擇, 除了浪費系統資源之外,還有可能在複製的時候出錯,而且以後修改父類的代碼之後,還要修改相應子類中的代碼,實在太低效,這個時候就是調用未綁定方法的場景。

代碼示例:

複製代碼
class abc(object):
    def __init__(self, a):
        self.a = -int(a)

class Test(abc):
    def __init__(self, a, b):
        abc.__init__(self, a)   # 調用父類的構造器,並手動傳遞 self
        self.b = b

    def fangfa(self):
        print self.a + self.b   # 屬性 a 由父類的構造器創建,b 由子類構造器創建

a = Test(123, 321)  # 我們只創建了子類的實例,而沒有創建父類的實例
a.fangfa()
複製代碼

 

  本來我們沒有創建父類的示例,是無法調用父類的實例方法的,但是我們手動傳遞了實例方法需要的 self 參數,就可以實現調用了。

  這裡的順序是,我們創建了 Test 的實例,其 self 是自動傳遞的,故 Test 的構造方法 __init__(self, a, b) 中 self 就代表實例 a,而我們又調用了父類的 abc.__init__(self, a) 這裡的 self 就是子類的實例 a ,參數 a 就是我們傳的 123,而父類中 self.a = -int(a) ;最後我們可在子類的方法中調用 self.a 這個屬性。

2.Python面向對象的三大特性

一、繼承

  面向對象中的繼承就是繼承的類直接擁有被繼承類的屬性而不需要在自己的類體中重新再寫一遍,其中被繼承的類叫做父類、基類,繼承的類叫做派生類、子類。在python3中如果不指定繼承哪個類,預設就會繼承Object類,而繼承了Object類的類就叫做新式類,而在python2中如果不指定繼承哪個類也不會預設去繼承Object類,而沒有繼承Object類的類就叫做經典類。經典類和新式類的不同就在於對方法的搜索順序不同,經典類是深度優先即先找自己類內,如果沒有就找左邊第一個父類,沒找到繼續從這個父類的父類中找依次類推直到找到最上一級的父類也沒找到再找左邊第二個父類,然後再重覆之前的過程,直到所有父類找一遍沒找到就報錯;而新式類是廣度優先,當下一個類可以通過其他類找到時就先不去找它,而是找繼承關係中與它的子類同級的其他類,依次類推直到最後找到object類沒有找到指定方法就報錯。新式類搜索順序圖示如下,還可以通過類名.mro()查看新式類繼承中的屬性搜索順序

 

 二、單繼承與多繼承

  在其他語言中只支持單繼承即class 類名(父類名),而python支持多繼承,用逗號將多個父類隔開即class 類名(父類名1,父類名2,。。。。)

 

  三、繼承與抽象

  抽象就是把一類事物的共有特性提取出來,繼承則是把父類的屬性拿過來並且還擁有自己的屬性。抽象是包含的範圍越來越大,共性越來越少,繼承則是包含的返回越來越小,共性越來越多。我們定義父類的過程就是抽象,定義子類的過程就是繼承。

 

 四、父類方法重寫

 我們把子類有而父類沒有的方法叫做子類的派生方法,而父類有子類也有的方法叫做對父類方法的重寫,因為按照類方法的搜索順序一個方法如果在子類中有就不會再從父類中找了,結果就是父類中的方法無法調用了,如果既想執行父類中的方法同時在子類中又能定義新功能,就需要先把父類中的這個方法單獨繼承過來,在python中只能使用父類名.方法名(self,父類的其他參數)的方式,在python3中可以使用super函數來實現,比如super().父類方法名(除self外的其他參數),其實在super函數中還需要傳入子類名和子類對象(在類中用self),但是我們使用時不需要特意去傳,除非在類外單獨調用父類的方法。註意在繼承父類方法時父類的參數除了需要在父類的方法中傳遞還需要在子類重寫的方法中傳遞

複製代碼
class Animal:
    def __init__(self,name,life_value,aggr):
        self.name=name
        self.life_value=life_value
        self.aggr=aggr
    def eat(self):
        self.life_value+=10

class Person(Animal):
    def __init__(self,money,name,life_value,aggr):
        super().__init__(name,life_value,aggr)
        self.money=money
    def attack(self,obj):
        obj.life_value-=self.aggr
複製代碼

 

  五、介面類

   介面類是用於規範子類的方法名定義用的,繼承介面類的子類可以不存在任何邏輯上的關係但是都需要實現某些共同的方法,為了讓這些子類的方法名能夠統一以便之後調用這些方法時不需要關註具體的對象就用介面類規範了這些方法的名字,子類一旦繼承了介面類就必須實現介面類中定義的方法,否則在子類實例化的時候就會報錯,而介面類本身則不需要實現去實現這些方法。

   

複製代碼
 1 from abc import ABCMeta,abstractmethod
 2 class Payment(metaclass=ABCMeta):
 3     @abstractmethod
 4     def pay(self,money):pass
 5 
 6 class Wechatpay(Payment):
 7     def pay(self,money):  #子類中必須定義介面類中有的方法,否則實例化會報錯
 8         pass
 9 
10 w1=Wechatpay()
複製代碼

 

  六、抽象類

   抽象類的作用和介面類一樣,只是繼承它的子類一般存在一些邏輯上的關係,且抽象類中的方法可以去實現,子類在重寫時用super函數調用抽象類的方法即可,同時在用抽象類時使用單繼承,使用介面類時使用多繼承

 

  七、多態

   多態就是不同的對象可以調用相同的方法然後得到不同的結果,有點類似介面類的感覺,在python中處處體現著多態,比如不管你是列表還是字元串還是數字都可以使用+和*。

 

  八、封裝

  封裝就是把類中的屬性和方法定義為私有的,方法就是在屬性名或方法名前加雙下劃線,而一旦這樣定義了屬性或方法名後,python會自動將其轉換為_類名__屬性名(方法名)的格式,在類的內部調用還是用雙下劃線加屬性名或方法名,在類的外部調用就要用_類名__屬性名(方法名)。父類的私有屬性和方法,子類無法對其進行修改。

 

  九、類的裝飾器 

  property屬性裝飾器:將類內的方法的調用方式和屬性一樣,這個裝飾器還有和其配套的setter、deleter。

   

複製代碼
class Demo:
    @property
    def p(self):
        print('property func')
    @p.setter
    def p(self,num):
        print('property_setter')
    @p.deleter
    def p(self):
        print('在刪除')
d=Demo()
d.p  
d.p=10
del d.p
--------------------------------------------------------------------------------------
property func
property_setter
在刪除
複製代碼

 

   staticmethod靜態方法裝飾器:將類內的方法變成普通的函數,或者把類外的函數放到類內當作方法調用

   

複製代碼
class A:
    @staticmethod
    def sum():   #這個方法跟普通函數沒有區別
        print('staticmethod')
A.sum() #用類名調用
--------------------------------------------------------------------------------------
staticmethod
複製代碼

  classmethod類方法裝飾器:該方法用於操作類屬性,無法操作對象屬性

  

複製代碼
class A:
    role='male'
    @classmethod
    def sum(cls):   #用於操作類屬性
        print(cls.role)
A.sum() #用類名調用
--------------------------------------------------------------------------------------
male
複製代碼

 

  十、isinstance和type的區別以及issubclass

   isinstance和type都可以用於判斷對象和指定類間的關係,但是isinstance的判斷沒有type準確,它無法正確判斷子類的對象和其父類的關係

   

複製代碼
class A:
    pass
class B(A):
    pass

b=B()
print(isinstance(b,B))
print(isinstance(b,A))
print(type(b) is B)
print(type(b) is A)
--------------------------------------------------------------------------------------
True
True
True
False
複製代碼

 

  issubclass用於判斷給定的兩個類,前者是否是後者的子類

 

  十一、反射

   hasattr(對象或類名,‘屬性或方法名’)  判斷指定的對象或類中是否存在指定的屬性或方法,有返回True

   getattr(對象或類名,'屬性或方法名')  獲取對象或類的指定屬性值或方法的記憶體地址

   setattr(對象或類名,‘新屬性名’,新屬性值) 給對象或類添加新的屬性或方法

   delattr(對象或類名,‘新屬性名’) 刪除之前添加的屬性

 

  十二、類的內置方法

  __doc__ :輸出類的描述信息

  __module__ :表示當前操作的對象在那個模塊

  __class__ :  表示當前操作的對象的類是什麼

  __dict__ :查看類或對象中的所有成員  類調用列印類的所有屬性,不包括實例屬性。實例調用列印所有實例屬性

  __str__ 格式化輸出%s輸出該方法的值

  __repr__  格式化輸出%r輸出該方法的值,並且%s在沒有__str__方法時也是輸出該方法的值
  __del__  del 執行該方法
  __getitem__  用對象加[]方式取值

  

複製代碼
class A:
    def __init__(self):
        self.names=['egon','alex','eva'] #可以是其他序列
    def __getitem__(self, item):
        print(self.names[item])

a=A()
a[1]
----------------------------------------------------------
alex
複製代碼

 


  __setitem__   添加值
  __delitem__  刪除值
  __new__ 用於創建沒有屬性的對象,調用object的__new__即可不需要自己實現。可以利用該方法實現單例模式
  __call__ 對象加括弧執行該方法
  __len__  len()執行該方法
  __eq__  ==運算輸出該方法的值

  __hash__ hash執行該方法

 

二丶代碼實現(三維向量類)

 

 1 class Vecter3:
 2     def __init__(self, x=0, y=0, z=0):
 3         self.X = x
 4         self.Y = y
 5         self.Z = z
 6     def __add__(self, n):
 7         r = Vecter3()
 8         r.X = self.X + n.X
 9         r.Y = self.Y + n.Y
10         r.Z = self.Z + n.Z
11         return r
12     def __sub__(self, n):
13         r = Vecter3()
14         r.X = self.X - n.X
15         r.Y = self.Y - n.Y
16         r.Z = self.Z - n.Z
17         return r
18     def __mul__(self, n):
19         r = Vecter3()
20         r.X = self.X * n
21         r.Y = self.Y * n
22         r.Z = self.Z * n
23         return r
24     def __truediv__(self, n):
25         r = Vecter3()
26         r.X = self.X / n
27         r.Y = self.Y / n
28         r.Z = self.Z / n
29         return r
30     def __floordiv__(self, n):
31         r = Vecter3()
32         r.X = self.X // n
33         r.Y = self.Y // n
34         r.Z = self.Z // n
35         return r
36     def show(self):
37         print((self.X,self.Y,self.Z))
38 
39 v1 = Vecter3(1,2,3)
40 
41 v2 = Vecter3(4,5,6)
42 
43 v3 = v1+v2
44 
45 v3.show()
46 
47 v4 = v1-v2
48 
49 v4.show()
50 
51 v5 = v1*3
52 
53 v5.show()
54 
55 v6 = v1/2
56 
57 v6.show()

此類可實現三維向量的加減乘除

運行後為

三丶代碼實現(程式類)

這個程式運用類與正則表達式匹配來寫,可以刪除重覆的英文並輸出,這裡輸入 This is my name

import re
class Good:
    def __init__(self,n):
        self.n = n
    def love(self):
        s1 = re.split(r' ',self.n)
        s2 = sorted(set(s1),key=s1.index)
        print(s2)
b = Good('This is is my name')#此處可自行輸入字元串
b.love()

接下來我們看運行結果

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • [ {"countryname":"","name":"請選擇","currency":""}, {"countryname":"歐洲貨幣聯盟","name":"歐元","currency":"EUR"}, {"countryname":"冰島","name":"冰島克朗",&q ...
  • 摘要: JS還可以這麼玩~ "Fundebug" 經授權轉載,版權歸原作者所有。 這是一篇有趣的文章,我們精選了 JS13K 游戲編程挑戰的優秀作品,與大家分享。JS13K 是專為 JavaScript 開發者量身定製的編程競賽,報名參賽的開發者需要根據挑戰主題,利用 JS 開發一款不超過 13KB ...
  • 定義: 定義: 將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。 結構:(書中圖,侵刪) 一個產品類 一個指定產品各個部件的抽象創建介面 若幹個實現了各個部件的具體實現的創建類 一個指揮者,用於控制具體的創建過程,包含一個抽象創建介面的引用 實例: 實例: 書中使用了游戲中 ...
  • (一)存儲選擇:微型對象資料庫 這裡是隨筆,不會詳述內容,下麵都是用實驗樣例來解釋說明。不明白的可以閃人了。 1。微型對象資料庫 例: { "食指":{ "對象名":"食指" "左右手":"左手" "屬性":[ {"重量":"0.1公斤"}, {"膚色":"黃"}, {"皮膚面積":"0.05平米" ...
  • 閱讀目錄 一、裝飾器 1、裝飾器的概念 #裝飾器定義:本質就是函數,功能是為其他函數添加附加功能 二、裝飾器需要遵循的原則 三、實現裝飾器知識儲備 四、高階函數 五、函數嵌套 六、閉包 1、閉包 2、函數閉包裝飾器基本實現 3、函數閉包加上返回值 4、函數閉包加上參數 使用可變長參數代碼如下:達到的 ...
  • 在分散式項目中,為了提高系統的可用性,服務提供者一般都會做集群處理,當其中一個服務出現宕機的時候,集群的其他服務仍然能夠提供服務,從而提高系統的可靠性。 常用的負載均衡演算法有: 隨機演算法 加權隨機演算法 輪詢演算法 加權輪詢演算法 最小時延演算法 一致性hash演算法 負載均衡追求的是每個服務提供者的負載一致 ...
  • 上個月,學習群里的 S 同學問了個題目,大意可理解為列表降維 ,例子如下: 原始數據是一個二維列表,目的是獲取該列表中所有元素的具體值。從抽象一點的角度來理解,也可看作是列表解壓或者列表降維。 這個問題並不難,但是,怎麼寫才比較優雅呢? 這種方法簡單粗暴,需要拼接什麼內容,就取出來直接拼接。然而,如 ...
  • 一、動態語⾔的定義 動態語言是在運行時確定數據類型的語言。變數使用之前不需要類型聲明,通常變數的類型是被賦值的那個值的類型。現在比較熱門的動態語言有:Python、PHP、JavaScript、Objective-C等,而 C 、 C++ 等語言則不屬於動態語言。 二、運行的過程中給對象綁定(添加) ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...