1. 程式人生 > 其它 >Python面向物件(一)

Python面向物件(一)

面向物件基礎

1. 面向物件

想要通過面向物件去實現某個或某些功能時需要2步:

  • 定義類,在類中定義方法,在方法中去實現具體的功能。

  • 例項化類並的個一個物件,通過物件去呼叫並執行方法。

class Message:

    def send_email(self, email, content):
        data = "給{}發郵件,內容是:{}".format(email,content)
        print(data)


msg_object = Message() # 例項化一個物件 msg_object,建立了一個一塊區域。
msg_object.send_email("[email protected]","註冊成功")

注意:1.類名稱首字母大寫&駝峰式命名;

​ 2.py3之後預設類都繼承object;

​ 3.在類中編寫的函式稱為方法;

​ 4.每個方法的第一個引數是self。

類中可以定義多個方法,例如:

class Message:

    def send_email(self, email, content):
        data = "給{}發郵件,內容是:{}".format(email, content)
        print(data)

    def send_wechat(self, vid, content):
        data = "給{}發微信,內容是:{}".format(vid, content)
        print(data)


msg_object = Message()
msg_object.send_email("[email protected]", "註冊成功")
msg_object.send_wechat("dean", "註冊成功")

1.1 物件和self

在每個類中都可以定義個特殊的:__init__ 初始化方法 ,在例項化類建立物件時自動執行,即:物件=類()

class Message:

    def __init__(self, content):
        self.data = content

    def send_email(self, email):
        data = "給{}發郵件,內容是:{}".format(email, self.data)
        print(data)

    def send_wechat(self, vid):
        data = "給{}發微信,內容是:{}".format(vid, self.data)
        print(data)

# 物件 = 類名() # 自動執行類中的 __init__ 方法。

# 1. 根據型別建立一個物件,記憶體的一塊 區域 。
# 2. 執行__init__方法,模組會將建立的那塊區域的記憶體地址當self引數傳遞進去。    往區域中(data="註冊成功")
msg_object = Message("註冊成功")

msg_object.send_email("[email protected]") # 給[email protected]發郵件,內容是:註冊成功
msg_object.send_wechat("dean") # 給dean發微信,內容是:註冊成功
  • 物件,讓我們可以在它的內部先封裝一部分資料,以後想要使用時,再去裡面獲取。
  • self,類中的方法需要由這個類的物件來觸發並執行( 物件.方法名 ),且在執行時會自動將物件當做引數傳遞給self,以供方法中獲取物件中已封裝的值。

注意:除了self預設引數以外,方法中的引數的定義和執行與函式是相同。

當然,根據類也可以建立多個物件並執行其中的方法,例如:

class Message:

    def __init__(self, content):
        self.data = content

    def send_email(self, email):
        data = "給{}發郵件,內容是:{}".format(email, self.data)
        print(data)

    def send_wechat(self, vid):
        data = "給{}發微信,內容是:{}".format(vid, self.data)
        print(data)


msg_object = Message("註冊成功")
msg_object.send_email("[email protected]") # 給[email protected]發郵件,內容是:註冊成功
msg_object.send_wechat("dean")


login_object = Message("登入成功")
login_object.send_email("[email protected]") # 給[email protected]發郵件,內容是:登入成功
login_object.send_wechat("dean")

面向物件的思想:將一些資料封裝到物件中,在執行方法時,再去物件中獲取。

函式式的思想:函式內部需要的資料均通過引數的形式傳遞。

  • self,本質上就是一個引數。這個引數是Python內部會提供,其實本質上就是呼叫當前方法的那個物件。

  • 物件,基於類例項化出來”一塊記憶體“,預設裡面沒有資料;經過類的 __init__方法,可以在記憶體中初始化一些資料。

1.2 常見成員

在編寫面向物件相關程式碼時,最常見成員有:

  • 例項變數,屬於物件,只能通過物件呼叫。
  • 繫結方法,屬於類,通過物件呼叫 或 通過類呼叫。
class Person:

    def __init__(self, n1, n2):
        # 例項變數
        self.name = n1
        self.age = n2
	
    # 繫結方法
    def show(self):
        msg = "我叫{},今年{}歲。".format(self.name, self.age)
        print(msg)

    def all_message(self):
        msg = "我是{}人,我叫{},今年{}歲。".format(Person.country, self.name, self.age)
        print(msg)

    def total_message(self):
        msg = "我是{}人,我叫{},今年{}歲。".format(self.country, self.name, self.age)
        print(msg)
# 執行繫結方法
p1 = Person("dean",20)
p1.show()
# 或
# p1 = Person("dean",20)
# Person.show(p1)


# 初始化,例項化了Person類的物件叫p1
p1 = Person("dean",20)

2. 三大特性

面向物件程式設計在很多語言中都存在,這種程式設計方式有三大特性:封裝、繼承、多型。

2.1 封裝

封裝主要體現在兩個方面:

  • 將同一類方法封裝到了一個類中
  • 將資料封裝到了物件中,在例項化一個物件時,可以通過__init__初始化方法在物件中封裝一些資料,便於以後使用。

2.2 繼承

子類可以繼承父類中的方法和類變數(不是拷貝一份,父類的還是屬於父類,子類可以繼承而已)。

父類
子類

基類
派生類
class Base:

    def func(self):
        print("Base.func")

class Son(Base):
    
    def show(self):
        print("Son.show")
        
s1 = Son()
s1.show()
s1.func() # 優先在自己的類中找,自己沒有才去父類。

s2 = Base()
s2.func()
class Base:
    def f1(self):
        pass

class Foo(Base):

    def f2(self):
        pass
    
class Bar(Base):
    
    def f3(self):
        pass
    
o1 = Foo()
o1.f2()
o1.f1()

小結:

  • 執行物件.方法時,優先去當前物件所關聯的類中找,沒有的話才去父類中查詢。
  • Python支援多繼承:先繼承左邊、再繼承右邊的。
  • 去self對應的那個類中去獲取成員,沒有就按照繼承關係向上查詢 。

在Python3中編寫類時,預設都會繼承object(即使不寫也會自動繼承)。

class Foo:
    pass

class Foo(object):
    pass

這一點在Python2是不同的:

  • 繼承object,新式類(繼承順序採用C3演算法)
  • 不繼承object,經典類(多繼承深度優先)

2.3 多型

在java或其他語言中的多型是基於:介面 或 抽象類和抽象方法來實現,讓資料可以以多種形態存在。

在Python中則不一樣,由於Python對資料型別沒有任何限制,所以他天生支援多型,Python中一切皆物件。

def func(arg):
    v1 = arg.copy() # 淺拷貝
    print(v1)
    
func("dean")
func([11,22,33,44])
class Email(object):
    def send(self):
        print("發郵件")

        
class Message(object):
    def send(self):
        print("發簡訊")
        
        
        
def func(arg):
    v1 = arg.send()
    print(v1)
    

v1 = Email()
func(v1)

v2 = Message()
func(v2)

在程式設計中,鴨子型別(duck typing)是動態型別的一種風格。在鴨子型別中,關注點在於物件的行為,能作什麼;而不是關注物件所屬的型別,例如:一隻鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那麼這隻鳥可以被稱為鴨子。

小結:

  • 封裝,將方法封裝到類中 或 將資料封裝到物件中,便於以後使用。

  • 繼承,將類中的公共的方法提取到基類中去實現。

  • 多型,Python預設支援多型(這種方式稱之為鴨子型別)

3. 再看資料型別

Python中一切皆物件,str、list、dict等資料型別,他們其實都是一個類,根據類可以建立不同類的物件。

# 例項化一個str類的物件v1
v1 = str("dean") 

# 通過物件執行str類中的upper方法。
data = v1.upper()

print(data)