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)