乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      一文看懂Python面向?qū)ο缶幊毯诵乃枷?Python學習與Django入門必看)

       省心省心省心 2020-03-14

      盡管網(wǎng)上有許多關(guān)于Python面向?qū)ο竦木幊探榻B,小編我看完后總覺得不是很滿意,也不過癮,所以決定自己親自動手寫篇文章,幫你理解Python面向?qū)ο蟮木幊痰幕靖拍詈秃诵乃枷?。本文?nèi)含很多實例代碼,以幫助新手更好理解。如果你在學習基于Python的Django Web開發(fā)框架,本文也會對你非常有幫助,因為Django編程就是采用面向?qū)ο蟮木幊獭?/span>

      類(Class)與對象(Object)

      類(Class)是用來描述具有相同屬性(Attribute)方法(Method)對象的集合。對象(Object)是類(Class)的具體實例。比如學生都有名字和分數(shù),他們有著共同的屬性。這時我們就可以設計一個學生類, 用于記錄學生的名字和分數(shù),并自定義方法打印出他們的名字和方法。

      • 屬性(Attribute): 類里面用于描述所有對象共同特征的變量或數(shù)據(jù)。比如學生的名字和分數(shù)。

      • 方法(Method): 類里面的函數(shù),用來區(qū)別類外面的函數(shù), 用來實現(xiàn)某些功能。比如打印出學生的名字和分數(shù)。

      要創(chuàng)建一個類我們需要使用關(guān)鍵詞class. 這個學生類Student看上去應該是這樣的:

      # 創(chuàng)建一個學生類
      class Student:
         
         # 定義學生屬性,初始化方法
         
      def __init__(self, name, score):
             self.name = name
             self.score = score

         # 定義打印學生信息的方法
         
      def show(self):
             print("Name: {}. Score: {}".format(self.name, self.score))

      在這個案例中,我們只定義了一個抽象的類,電腦并沒有創(chuàng)建什么存儲空間。只有當我們完成類的實例化(Instance)時,電腦才會創(chuàng)建一個具體的對象(Object),并為之分配存儲空間。所以對象(Object)是類(Class)的一個實例。

      要創(chuàng)建一個具體的學生對象(Object),我們還需要輸入:

      student1 = Student("John", 100)
      student2 = Student("Lucy", 99)

      在這個案例中,Student是類,student1和student2是我們創(chuàng)建的具體的學生對象。當我們輸入上述代碼時,Python會自動調(diào)用默認的__init__初始構(gòu)造函數(shù)來生成具體的對象。關(guān)鍵字self是個非常重要的參數(shù),代表創(chuàng)建的對象本身。

      當你創(chuàng)建具體的對象后,你可以直接通過student1.namestudent1.score來分別獲取學生的名字和分數(shù),也可以通過student1.show()來直接打印學生的名字和分數(shù)。

      類變量(class variables)實例變量(instance variables)

      假設我們需要在Student類里增加一個計數(shù)器number,每當一個新的學生對象(Object)被創(chuàng)建時,這個計數(shù)器就自動加1。由于這個計數(shù)器不屬于某個具體學生,而屬于Student類的,所以被稱為類變量(class variables)。而姓名和分數(shù)屬于每個學生對象的,所以屬于實例變量(instance variables),也被稱為對象變量(object variables)。

      這個新Student類看上去應該是這樣的:

      # 創(chuàng)建一個學生類
      class Student:

         # number屬于類變量,定義在方法外,不屬于具體實例
         
      number = 0

         
      # 定義學生屬性,初始化方法
         # name和score屬于實例變量,定義在方法里
         
      def __init__(self, name, score):
             self.name = name
             self.score = score
             # 此處有錯誤
             number
      = number + 1

         
      # 定義打印學生信息的方法
         
      def show(self):
             print("Name: {}. Score: {}".format(self.name, self.score))

      類變量和實例變量的區(qū)別很大,訪問方式也也不一樣。

      • 類變量:類變量在整個實例化的對象中是公用的。類變量定義在類中且在函數(shù)體之外。訪問或調(diào)用類變量的正確方式是類名.變量名或者self.__class__.變量名。self.__class__自動返回每個對象的類名。

      • 實例變量:定義在方法中的變量,屬于某個具體的對象。訪問或調(diào)用實例變量的正確方式是對象名.變量名或者self.變量名.

      注意到上述Student類有個錯誤沒? 我們試圖直接使用number = number + 1調(diào)用屬于類的變量number。正確的方式是使用Student.numberself.__class__.number訪問屬于類的變量。下面的代碼才是正確的:

      # 創(chuàng)建一個學生類
      class Student:

         # number屬于類變量,不屬于某個具體的學生實例
         
      number = 0

         
      # 定義學生屬性,初始化方法
         # name和score屬于實例變量
         
      def __init__(self, name, score):
             self.name = name
             self.score = score
             
      Student.number = Student.number + 1

         
      # 定義打印學生信息的方法
         
      def show(self):
             print("Name: {}. Score: {}".format(self.name, self.score))

      # 實例化,創(chuàng)建對象
      student1 = Student("John", 100)
      student2 = Student("Lucy", 99)

      print(Student.number)  # 打印2
      print(student1.__class__.number) # 打印2

      類方法(Class method)

      正如同有些變量只屬于類,有些方法也只屬于類,不屬于具體的對象。你有沒有注意到屬于對象的方法里面都有一個self參數(shù), 比如__init__(self), show(self)? self是指對象本身。屬于類的方法不使用self參數(shù), 而使用參數(shù)cls,代表類本身。另外習慣上對類方法我們會加上@classmethod的修飾符做說明。

      同樣拿Student為例子,我們不用print函數(shù)打印出已創(chuàng)建學生對象的數(shù)量,而是自定義一個類方法來打印,我們可以這么做:

      class Student:

         # number屬于類變量,不屬于某個具體的學生實例
         
      number = 0

         
      # 定義學生屬性,初始化方法
         # name和score屬于實例變量
         
      def __init__(self, name, score):
             self.name = name
             self.score = score
             Student.number = Student.number + 1

         
      # 定義打印學生信息的方法
         
      def show(self):
             print("Name: {}. Score: {}".format(self.name, self.score))

         # 定義類方法,打印學生的數(shù)量
         
      @classmethod
         
      def total(cls):
             print("Total: {0}".format(cls.number))


      # 實例化,創(chuàng)建對象
      student1 = Student("John", 100)
      student2 = Student("Lucy", 99)

      Student.total()  # 打印 Total: 2

      類的私有屬性(private attribute)和私有方法(private method)

      類里面的私有屬性私有方法以雙下劃線__開頭。私有屬性或方法不能在類的外部被使用或直接訪問。我們同樣看看學生類這個例子,把分數(shù)score變?yōu)樗接袑傩?,看看會發(fā)生什么。

      # 創(chuàng)建一個學生類
      class Student:

         # 定義學生屬性,初始化方法
         # name和score屬于實例變量, 其中__score屬于私有變量
         
      def __init__(self, name, score):
             self.name = name
             self.__score = score

         # 定義打印學生信息的方法
         
      def show(self):
             print("Name: {}. Score: {}".format(self.name, self.__score))

      # 實例化,創(chuàng)建對象
      student1 = Student("John", 100)

      student1.show()  # 打印 Name: John, Score: 100
      student1.__score  # 打印出錯,該屬性不能從外部訪問。

      如果你將score變成__score, 你將不能直接通過student1.__score獲取該學生的分數(shù)。show()可以正常顯示分數(shù),是因為它是類里面的函數(shù),可以訪問私有變量。

      私有方法是同樣的道理。當我們把show()變成,__show()你將不能再通過student1.__show()打印出學生的名字和分數(shù)。值得注意的是私有方法必需含有self這個參數(shù),且把它作為第一個參數(shù)。

      在面向?qū)ο蟮木幊讨?通常情況下很少讓外部類直接訪問類內(nèi)部的屬性和方法,而是向外部類提供一些按鈕,對其內(nèi)部的成員進行訪問,以保證程序的安全性,這就是封裝。

      @property的用法與神奇之處

      在上述案例中用戶不能用student1.__score方式訪問學生分數(shù),然而用戶也就知道了__score是個私有變量。我們有沒有一種方法讓用戶通過student1.score來訪問學生分數(shù)而繼續(xù)保持__score私有變量的屬性呢?這時我們就可以借助python的@property裝飾器。我們可以先定義一個方法score(), 然后利用@property把這個函數(shù)偽裝成屬性。見下面例子:

      # 創(chuàng)建一個學生類
      class Student:

         # 定義學生屬性,初始化方法
         # name和score屬于實例變量, 其中score屬于私有變量
         
      def __init__(self, name, score):
             self.name = name
             self.__score = score

         # 利用property裝飾器把函數(shù)偽裝成屬性
         
      @property
         
      def score(self):
             print("Name: {}. Score: {}".format(self.name, self.__score))

      # 實例化,創(chuàng)建對象

      student1 = Student("John", 100)

      student1.score  # 打印 Name: John. Score: 100

      注意: 一旦給函數(shù)加上一個裝飾器@property,調(diào)用函數(shù)的時候不用加括號就可以直接調(diào)用函數(shù)了 

      類的繼承(Inheritance)

      面向?qū)ο蟮木幊處淼淖畲蠛锰幹痪褪谴a的重用,實現(xiàn)這種重用的方法之一是通過繼承(Inheritance)。你可以先定義一個基類(Base class)或父類(Parent class),再按通過class 子類名(父類名)來創(chuàng)建子類(Child class)。這樣子類就可以從父類那里獲得其已有的屬性與方法,這種現(xiàn)象叫做類的繼承。

      我們再看另一個例子,老師和學生同屬學校成員,都有姓名和年齡的屬性,然而老師有工資這個專有屬性,學生有分數(shù)這個專有屬性。這時我們就可以定義1一個學校成員父類,2個子類。

      # 創(chuàng)建父類學校成員SchoolMember
      class SchoolMember:

         def __init__(self, name, age):
             self.name = name
             self.age = age

         def tell(self):
             # 打印個人信息
             
      print('Name:"{}" Age:"{}"'.format(self.name, self.age), end=" ")


      # 創(chuàng)建子類老師 Teacher
      class Teacher(SchoolMember):

         def __init__(self, name, age, salary):
             SchoolMember.__init__(self, name, age) # 利用父類進行初始化
             
      self.salary = salary

         # 方法重寫
         
      def tell(self):
             SchoolMember.tell(self)
             print('Salary: {}'.format(self.salary))


      # 創(chuàng)建子類學生Student
      class Student(SchoolMember):

         def __init__(self, name, age, score):
             SchoolMember.__init__(self, name, age)
             self.score = score

         def tell(self):
             SchoolMember.tell(self)
             print('score: {}'.format(self.score))


      teacher1 = Teacher("John", 44, "$60000")
      student1 = Student("Mary", 12, 99)

      teacher1.tell()  # 打印 Name:"John" Age:"44" Salary: $60000
      student1.tell()  # Name:"Mary" Age:"12" score: 99

      上述代碼中,你注意到以下幾點了嗎?

      • 在創(chuàng)建子類的過程中,你需要手動調(diào)用父類的構(gòu)造函數(shù)__init__來完成子類的構(gòu)造。

      • 在子類中調(diào)用父類的方法時,需要加上父類的類名前綴,且需要帶上self參數(shù)變量。比如SchoolMember.tell(self), 這個可以通過使用super關(guān)鍵詞簡化代碼。

      • 如果子類調(diào)用了某個方法(如tell())或?qū)傩裕?/span>Python會先在子類中找,如果找到了會直接調(diào)用。如果找不到才會去父類找。這為方法重寫帶來了便利。

      實際Python編程過程中,一個子類可以繼承多個父類,原理是一樣的。第一步總是要手動調(diào)用__init__構(gòu)造函數(shù)。

      super()關(guān)鍵字調(diào)用父類方法

      在子類當中可以通過使用super關(guān)鍵字來直接調(diào)用父類的中相應的方法,簡化代碼。在下面例子中,學生子類調(diào)用了父類的tell()方法。super().tell()等同于SchoolMember.tell(self)。當你使用Python super()關(guān)鍵字調(diào)用父類方法時時,注意去掉括號里self這個參數(shù)。

      # 創(chuàng)建子類學生Student
      class Student(SchoolMember):

         def __init__(self, name, age, score):
             SchoolMember.__init__(self, name, age)
             self.score = score

         def tell(self):
             super().tell() # 等同于 SchoolMember.tell(self)
             
      print('score: {}'.format(self.score))

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約