day20-面向對象基礎

面向對象基礎

面向過程編程與面向對象編程

面向過程編程

面向過程編程的核心是過程,過程指的是解決問題的步驟。基於面向過程編程的思想編寫程序比如在設計一條流水線,是一種機械式的思惟方式。mysql

  • 優勢:邏輯清晰(邏輯一步一步的,比較系統)
  • 缺點:擴展性差(上一個函數的輸出是下一個函數的輸入,若是改動某項功能時會影響其餘功能)

面向對象編程

面向對象編程的核心是對象,在python中一切皆對象,對象就是特徵和技能的結合體。基於面向對象編程就是定義出一個個鮮明獨特的對象,而後經過對象之間交互編程sql

  • 優勢:擴展性很是強
  • 缺點:編程的複雜度要高於面向過程

類與對象

類的意思是分類、類別。好比在學校中:按照學生和老師能夠劃分兩類,一個是學生類,他們都具備名字、學號、班級以及選課、聽課;一個是老師類,他們都有名字以及授課。所以給出類的定義:類就是一系列對象類似的特徵與技能的結合體數據庫

對象

在python中一切皆對象,根據劃分稱爲某類下的一個對象,好比貓是動物類的對象,人是人類的對象編程

在顯示世界中:先有對象,再有類;在程序中,務必保證先定義類,後產生對象app

定義類和對象

定義類:函數

# 注意類中定義變量使用駝峯體
class OldboyStudent:
    school = 'oldboy'
    def choose_course(self):
        print('is choosing course')
        
oldboystudent_dict = OldboyStudent.__dict__  ## 雙下劃線開頭的方法會在某種狀況下自動觸發

曾經定義函數,函數只檢測語法,不執行代碼,可是定義類的時候,代碼會在類定義階段就馬上執行,而且會產生一個類的名稱空間,也就是說類的自己其實就是一個容器/名稱空間,是用來存放名字的,這是類的用途之一學習

print(oldboystudent_dict)    # 打印的是該類名稱空間裏具備的名字,如咱們定義的school,choose_course和內置的其餘屬性
{'__module__': '__main__', 'school': 'oldboy', 'choose_course': <function OldboyStudent.choose_course at 0x000001BCAD3A2048>, '__dict__': <attribute '__dict__' of 'OldboyStudent' objects>, '__weakref__': <attribute '__weakref__' of 'OldboyStudent' objects>, '__doc__': None}
print(oldboystudent_dict['school'])  # 取school的值
oldboy
print(oldboystudent_dict['choose_course'])
print(type(oldboystudent_dict['choose_course']))
<function OldboyStudent.choose_course at 0x000001BCAD3A2048>
<class 'function'>
oldboystudent_dict['choose_course']('nick')
is choosing course
print(OldboyStudent.school)
oldboy
OldboyStudent.choose_course('nick')
is choosing course

定義對象:調用類便可產生對象,調用類的過程,又稱爲類的實例化,實例化的結果稱爲類的對象/實例ui

stu1 = OldboyStudent()  # 調用類會獲得一個返回值,該返回值就是類的一個具體存在的對象/實例
print(1, stu1.school)
stu1.choose_course()

stu2 = OldboyStudent()  # 調用類會獲得一個返回值,該返回值就是類的一個具體存在的對象/實例
print(2,stu2.school)
stu2.choose_course()
1 oldboy
is choosing course
2 oldboy
is choosing course

定製對象獨有特徵

類中定義的函數是類的函數屬性,類可使用,對象也可使用。若是類的屬性改了,則對象的屬性也會隨之改變。但同一類中的對象都會具本身獨特的特徵,好比張三身高180,李四身高175。設計

class OldboyStudent:
    school = 'oldboy'
    def choose_course(self):
        print('is choosing course')
        
stud1 = OldboyStudent()
stud2 = OldboyStudent()
print(stud1.__dict__)
{}
print(stud2.__dict__)
{}

對象本質相似於類,也是一個名稱空間,可是對象的名稱空間存放對象獨有的名字,而類中存放的是對象們共有的名字。所以咱們能夠直接爲對象單獨定製名字。

stud1.name = 'nick'
stud1.age = 18
print(stud1.name,stud1.age)
nick 18
print(OldboyStudent.name)  # 在對象中定義的獨有屬性,不屬於類
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-49-d5096aff41d0> in <module>
----> 1 print(OldboyStudent.name)
AttributeError: type object 'OldboyStudent' has no attribute 'name'

使用上述方法雖然讓咱們定製屬性更簡單,可是仍是太麻煩了,若是能夠在實例化對象的時候自動觸發定時屬性,那就更方便了,所以可使用類的__init__方法。

class OldboyStudent:
    school = 'oldboy'
    # 調用類的時候自動觸發
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def choose_course(self):
        print('is choosing course')

stud1 = OldboyStudent('nick', 18)
print(stud1.__dict__, stud1.name, stud1.age)
{'name': 'nick', 'age': 18} nick 18

經過上述現象能夠發現,調用類的時候創造了一個空對象,同時自動觸發類中__init__功能,將stud1以及調用類括號內的參數一同傳入

對象屬性查找順序

class OldboyStudent:
    school = 'oldboy'
    name = 'tank'
    # 調用類的時候自動觸發
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def choose_course(self):
        print('is choosing course')

stud1 = OldboyStudent('nick', 18)
print(stud1.name, stud1.school)
nick oldboy
print(stud1.height)
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-61-ff2d39934944> in <module>
----> 1 print(stud1.height)
AttributeError: 'OldboyStudent' object has no attribute 'height'
  • 類中定義name爲tank,定義對象時傳入name爲nick,在打印stud1.name時打印的是nick。可見:當類和對象同時定義屬性時,先從對象自己查找
  • 類中定義school爲oldboy,對象中未定義,打印stud1.school時打印的是oldboy。可見:當對象中未定義該屬性時,從類中查找
  • 類和對象都未定義時,則報錯

總結:查找屬性先從對象自己查找,對象沒有去類中查找,類中也沒有則報錯

類與對象的綁定方法

class OldboyStudent:
    school = 'oldboy'
    name = 'tank'
    # 調用類的時候自動觸發
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def choose_course(self):
        print('is choosing course')

stud1 = OldboyStudent('nick', 18)  # 每次實例化對象的時候都會自動調用__init__方法(排在第一位)
stud1.choose_course()
is choosing course
OldboyStudent.choose_course()  # 報錯,提示缺乏參數self
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-77-d104c34c78e5> in <module>
----> 1 OldboyStudent.choose_course()  # 報錯,提示缺乏參數self
TypeError: choose_course() missing 1 required positional argument: 'self'
OldboyStudent.choose_course('nick')  # 將nick傳給形參self,相似於普通函數調用
is choosing course

在類調用類中定義的函數時,須要傳值給self;在對象調用類中定義的函數時,不須要傳入參數。

總結:

  • 類中定義的函數是類的函數屬性,類可使用,但使用的就是一個普通的函數而已,意味着須要徹底遵循函數的參數規則,該傳幾個值就傳幾個
  • 類中定義的函數對象也可使用,並且是綁定給對象用的,綁定給誰,就應該由誰來調用,誰來調用就會將誰看成第一個參數自動傳入。因此不須要傳參給self
  • 類定義的函數大多狀況下都是綁定給對象用的,因此在類中定義的函數都應該自帶一個參數self

類與數據類型

以前在學習定義數據時,好比定義一個列表,可使用lis = list([1,2,3])。其實list就是一個類,lis就是list類中的一個實例化對象。只不過這個list類是python爲咱們封裝好的,咱們能夠直接調用生成一個列表。而append就是list類定義的一個函數方法,對象lis也能夠直接調用。其餘數據類型也是同理

總結:python3中統一了類與類型的概念,類就是類型。所以數據類型就是將數據分紅不一樣的類,生成一個具體的數據時就是在生成一個類的對象

對象的高度整合

  • 以將來咱們要鏈接數據庫舉例,若是沒有面向對象的思想,咱們只要想要使用一個方法,就必須得這樣作
import pymysql  # 鏈接mysql的三方庫,能夠pip3 install pymysql安裝
def exc1(host, port, db, charset, sql):
    conn = pymysql.connect(host, port, db, charset)
    conn.execute(sql)
    return xxx
def exc2(proc_name):
    conn = pymysql.connect(host, port, db, charsett)
    conn.call_proc(sql)
    return xxx
exc1('1.1.1.1', 3306, 'db1', 'utf-8', 'select * from t1')
exc1('1.1.1.1', 3306, 'db1', 'utf-8', 'select * from t2')
exc1('1.1.1.1', 3306, 'db1', 'utf-8', 'select * from t3')
exc1('1.1.1.1', 3306, 'db1', 'utf-8', 'select * from t4')
  • 有了面向對象以後,對於上述的例子,咱們能夠這樣作
import pymysql
class Foo:
    def __init__(self, host, port, db, chartset):
        self.host = host
        self.port = port
        self.db = db
        self.charset = chartset
    def exc1(self, sql):
        conn = pymysql.connect(self.host, self.port, self.db, self.charset)
        conn.execute(sql)
        return xxx
    def exc2(self, proc_name):
        conn = pymysql.connect(self.host, self.port, self.db, self.charsett)
        conn.call_proc(sql)
        return xxx
obj1 = Foo('1.1.1.1', 3306, 'db1', 'utf-8')
obj1.exc1('select * from t1')
obj1.exc1('select * from t2')
obj1.exc1('select * from t3')
obj1.exc1('select * from t4')

總結:對象其實就是一個高度整合的產物,整合數據與專門操做該數據的方法(綁定方法)

相關文章
相關標籤/搜索