1. 程式人生 > >11-python基礎知識-面向物件

11-python基礎知識-面向物件

面向物件

面向物件三大特點

  • 封裝:既是對資料結構的封裝,又是處理資料的方法的封裝。
  • 繼承:強調的是父子類的關係
  • 多型:不同物件呼叫相同的方法,有不同的響應。

類的繼承

  • 相關概念

    • 繼承:父類的屬性和方法,子類可以直接擁有,稱為繼承。
    • 派生:子類在父類的基礎上衍生出新的特徵(屬性或行為),稱為派生。
    • 總結:其實他們是一回事,知識描述問題的角度不同(繼承側重相同點,派生側重不同點)
  • 繼承語法

    # class Animal:
    # 當沒有寫父類時,預設繼承自object
    class
    Animal(object): def __init__(self, name): self.name = name def run(self): print('小動物喜歡一天到晚跑個不停') # 定義一個子類,繼承自Animal class Dog(Animal): pass d = Dog('旺財') # 可以直接擁有父類的屬性 print(d.name) # 也擁有父類的行為 d.run()
  • 派生示例

    class Animal:
        def run(self):
            print
    ('一天到晚跑個不停') class Cat(Animal): def eat(self): print('貓喜歡吃魚') c = Cat() c.run() # 新增的屬性 c.name = '加菲' print(c.name) # 衍生的方法 c.eat()
  • 方法重寫

        class Animal:
            def run(self):
                print('小動物喜歡到處跑')
    
            def eat(self):
                print('小動物喜歡吃東西')
                
        class
    Cat(Animal): # 父類方法完全不合適,覆蓋重寫 def run(self): print('貓喜歡走貓步') # 父類的方法不夠完善,需要新增完善 def eat(self): # 保留父類方法的內容 # Animal.eat(self) # 不建議使用 # super(Cat, self).eat() super().eat() # 推薦使用 # 新增完善的內容 print('貓喜歡吃魚') c = Cat() c.eat() c.run()
  • 多繼承:一個類可以有多個父類

    class A:
        def test(self):
            print('in class A  func test...')
            
    class B:
        def test(self):
            print('in class B  func test...')
    
        def eat(self):
            print('in class B func eat ...')   
            
    class C(A, B):
        def eat(self):
            # 預設的方式找父類,跟不重寫方法時的順序是一樣的,
            # 按照書寫的先後順序,預設是寫在前面的類的方法
            # super().eat()
            # 明確指定呼叫哪個父類的方法
            B.eat(self)
    
    c = C()
    c.test()
    c.eat()        
    
  • 許可權管理

    class Person:
          def __init__(self, name, age):
              self.name = name
              # 定義私有屬性
              self.__age = age
    
          def test(self):
              # 私有屬性和方法可以在類的內部使用
              print(self.__age)
              self.__hello()
              
          # 定義私有方法
          def __hello(self):
              print('for test')
              
    class Man(Person):
    	def show(self):
          	# 私有屬性和方法在子類也不可以使用
          	print(self.__age)
            
    p = Person('老王', 38)
    print(p.name)
    # 屬性前新增連個下劃線,類的外部不能使用
    # print(p.__age)
    
    # 預設在新增兩個下劃線的屬性名前添加了'_類名'
    # print(p.dict)
    # 強烈建議不要這樣使用
    # print(p._Person__age)
    
    p.test()
    # p.__hello()
    m = Man('小明', 18)
    # m.show()
    
  • 類屬性

    class Person:
        # 類屬性,屬於整個類
        # nation = '中國'
    
        # 限制物件可以使用的屬性,可以提高效率,節約儲存空間
        __slots__ = ('name', 'age', 'nation')
    
        def __init__(self, name):
            # 成員屬性,屬於某個物件
            self.name = name
            # 成員屬性,當不存在會會試著找一下類屬性
            # self.nation = 'xxx'
    
        def test(self):
            pass
    
    # 通過類名訪問類屬性
    # print(Person.nation)
    
    p = Person('王大花')
    # 可以通過物件訪問類屬性,但是不建議
    print(p.name)
    # print(p.nation)
    
    p.age = 20
    # p.height = 180
    
    # 特殊的類屬性
    # 類名字串
    print(Person.__name__)
    
    # 父類組成的元組
    print(Person.__bases__)
    
    # 類相關的資訊
    print(Person.__dict__)
    
    print(Person.__slots__)
    
  • 類方法

    • 說明
      • 提通過類名進行呼叫
      • 定義時需要使用裝飾器classmethod
    • 作用:
      • 可以建立物件或者簡潔的建立物件
      • 可以對外提供簡單易用的介面
    • 示例1:
    class Person:
        # 成員方法,通過物件進行呼叫
        def eat(self):
            print('紅燒雞腿我喜歡吃')
    
    	# 類方法,通過類名進行呼叫
        @classmethod
        def test(cls):
            # cls表示當前類
            print(cls, '類方法')
    
      	# 建立物件
        @classmethod
        def create(cls):
            obj = cls()
            obj.age = 1
            return obj     
         
    p = Person()
    p.eat()
    Person.test()
    # 建立或者簡潔的建立物件  
    p2 = Person.create()
    print(type(p2))
    
    • 示例2:
    class Number:
          def __init__(self, num1, num2):
              self.num1 = num1
              self.num2 = num2
    
          def add(self):
              return self.num1 + self.num2
    
          def sub(self):
              return self.num1 - self.num2
    
          def mul(self):
              return self.num1 * self.num2
    
          def div(self):
              if self.num2 == 0:
                  return None
              return self.num1 / self.num2
    
          # 對外提供簡單易用的介面
          @classmethod
          def pingfanghe(cls, num1, num2):
              n1 = cls(num1, num1)
              n12 = n1.mul()
              n2 = cls(num2, num2)
              n22 = n2.mul()
              n3 = cls(n12, n22)
              return n3.add()
    
    # 計算3^2 + 4^2
    # n1 = Number(3, 3)
    # n12 = n1.mul()
    #
    # n2 = Number(4, 4)
    # n22 = n2.mul()
    #
    # n3 = Number(n12, n22)
    # ret = n3.add()
    # print(ret)
    
    print(Number.pingfanghe(3, 4))
    
  • 靜態方法

    • 說明:
      • 通過裝飾器staticmethod修飾
      • 通過類名進行呼叫
    • 示例:
    class Person:
          # 靜態方法:沒有cls引數
          @staticmethod
          def test():
              print('static method test ...')
    
          # 靜態方法:可以建立物件
          @staticmethod
          def create():
              p = Person()
              p.age = 1
              return p
          
      Person.test()
      p = Person.create()
      print(type(p))  
    
    • 總結:
      • 凡是靜態方法能夠解決的問題類方法都能解決
      • 若方法中沒有涉及類名的操作,可以使用靜態方法代替類方法

多型特性

  • 定義:不同的物件,呼叫相同的方法,會有不同的響應

  • 示例:

    class Animal:
    	def run(self):
    		print('小動物走道都不一樣')
    
    class Cat(Animal):
        def run(self):
            print('貓都的是貓步')
            
    class Dog(Animal):
        def run(self):
            print('狗一般都走S型')
            
    def func(obj):
        obj.run()
     
    func(Cat())
    func(Dog())
    

屬性函式

  • 說明:可以將成員方法當做屬性一樣訪問

  • 作用:獲取時以及設定指定屬性時都可以進行人為干預,可以保護特定屬性

  • 示例:

    class User:
        def __init__(self, username, password):
            self.username = username
            self.__password = password
    
        # 可以將方法像訪問屬性一樣訪問
        @property
        def test(self):
            return 'hello'
    
        # 保護指定的屬性
        @property
        def password(self):
            print('大哥,有人想偷看密碼')
            return '哈哈,讓你偷看,沒門'
    
        # 在設定對應屬性時會自動呼叫
        @password.setter
        def password(self, password):
            print('密碼設定', password)
            # 人為干預密碼的設定過程,如:加密儲存密碼
            self.__password = 'xxx' + password + 'yyy'
            
    u = User('大狗', '123456')
    # u.test()
    # print(u.test)
    print(u.password)
    u.password = '654321'
    print(u.__dict__)
    

虛擬環境

  • 為什麼要使用虛擬環境?
    • 在同一個環境下,不同軟體依賴同一軟體包的不同版本,為了進行環境隔離就出現了虛擬環境
  • 虛擬環境建立工具:virtualenv
    • pip install virtualenv
  • 建立虛擬環境
    • virtualenv 虛擬環境目錄名
  • 啟用虛擬環境
    • 虛擬環境目錄\Scripts\activate.bat
  • 退出虛擬環境
    • 虛擬環境目錄\Scripts\deactivate.bat
  • 快速複製一個虛擬環境
    • 冷藏現有的虛擬環境:pip freeze > requirements.txt
    • 建立一個新的虛擬環境:virtualenv venv
    • 啟用虛擬環境:venv\Scripts\activate.bat
    • 安裝依賴:pip install -r requirements.txt
  • 虛擬環境管理工具:virtualenvwrapper-win
    • 安裝:pip install virtualenvwrapper-win
    • 說明:預設會將虛擬環境儲存在C:\Users\使用者名稱\Envs目錄下
    • 檢視虛擬環境:lsvirtualenv
    • 建立虛擬環境:mkvirtualenv
    • 啟動虛擬環境:workon 虛擬環境名
    • 退出虛擬環境:deactivate.bat