1. 程式人生 > >PythonOOP面向對象編程1

PythonOOP面向對象編程1

思想 類名 內部 oop 黃色 函數 and ati 關系

# Python面向對象編程1

什麽是對象?

  • 對象是指現實中的物體或實體(擁有一系列變量、函數(方法)的)

什麽事面向對象?

  • 把一切看成對象(實例),讓對象和對象之間建立關聯關系

對象都有什麽特征?

  • 屬性(名詞)實例變量
    • 姓名、年齡、性別
  • 行為(動作)實例方法
    • 學習、吃飯、睡覺

# class 類

什麽是類?

  • 擁有相同屬性和行為的對象分為一組,即為一個類,類是用來描述對象的工具,用類可以創建同類對象

車(類) -------> BYD E6 (京A.88888) 實例

    \  
     \----> BMW X5 (xxxxxx) 實例

狗(類) -------> 金毛犬 編號:007 實例

         \-----> 薩摩耶 編號:008 實例
     
對象 實例
class object instance

類的創建

  • 語法:

      class 類名(繼承列表)
      '''類的文檔字符串'''
      示例方法定義(類內的函數稱為方法method)  
      類變量定義  
      類方法定義  
      靜態方法定義
  • 作用:

    • 創建一個類
    • 用於描述此類對象的行為和屬性
    • 類用於創建此類的一個或多個對象(實例)
  • 構造函數

    • 表達式:類名([創建傳參列表])
    • 作用:創建這個類的實例對象,並返回此實例對象的引用關系
  • 實例(對象)說明

    • 實例有自己的作用域和名字空間,可以為該示例添加實例變量(屬性)
    • 示例可以調用類方法和示例方法
    • 示例可以訪問類和實例變量
class Dog: # 定義一個類,類名為Dog
    pass

dog1 = Dog() # 創建Dog類的對象
dog2 = Dog() # 創建Dog類的另一個對象

#類似如下語句:
int1 = int()
int2 = int()

method 實例方法

  • 語法:
    class 類名(繼承列表):
    def 實例方法名(self, 參數1, 參數2, ...)
    ‘‘‘實例方法的文檔字符串‘‘‘
    語句塊

  • 作用:
    • 用於描述一個對象的行為,讓此類型的全部對象都擁有相同的行為
  • 說明:
    • 實例方法實質是函數,是定義在類內的函數
    • 實例方法至少有一個形參,第一個形參代表調用這個方法的實例,一般命名為‘self‘
  • 實例方法的調用語法:
    實例.實例方法名(調用傳參)

    類名.示例方法名(實例調用傳參)

class Dog:
    def eat(self, food):
        '''此方法用來描述小狗吃東西的行為'''
        print("小狗正在吃:", food)
        
    def sleep(self, hour):
        print("小狗睡了:", hour, "小時")
    
    def play(self, obj):
        print("小狗正在玩:", obj)
    
# 創建一個Dog的類的實例
dog1 = Dog()
dog1.eat("狗糧")
dog1.sleep(1)
dog1.play("球")

# 創建另一個Dog對象
dog2 = Dog()
dog2.play("飛盤")
# 可以用以下方法代替
Dog.play(dog2, "雜技")

dog2.sleep(2)
dog2.eat("骨頭")
小狗正在吃: 狗糧
小狗睡了: 1 小時
小狗正在玩: 球
小狗正在玩: 飛盤
小狗正在玩: 雜技
小狗睡了: 2 小時
小狗正在吃: 骨頭

attribute 實例屬性(變量)

  • 每個實例都可以有自己的變量,此變量稱為實例變量(屬性)

  • 語法:
    實例.屬性名

  • 賦值規則:
    • 首次為屬性賦值則創建此屬性
    • 再次為屬性賦值則改變屬性的綁定關系
  • 作用:
    • 用來記錄對象自身的數據
class Dog:
    def eat(self, food):
        print(self.color, '的',
              self.kinds, '正在吃', food)
    pass

# 創建第一個對象
dog1 = Dog()
dog1.kinds = '金毛' # 添加屬性kinds
dog1.color = '白色' # 添加屬性color
dog1.color = '黃色' # 改變屬性color綁定關系
print(dog1.color, '的', dog1.kinds)

dog2 = Dog()
dog2.kinds = '薩摩耶'
dog2.color = '灰色'
print(dog2.color, '的', dog2.kinds)

dog1.eat("骨頭")
dog2.eat("包子")
黃色 的 金毛
灰色 的 薩摩耶
黃色 的 金毛 正在吃 骨頭
灰色 的 薩摩耶 正在吃 包子
  • 刪除屬性
    • 用 del 語句可以刪除一個對象的實例變量
    • 語法:
      del 對象.實例變量名
class Cat:
    pass

c1 = Cat()
c1.color = '白色'
print(c1.color)
del c1.color
白色

初始化方法

  • 作用:
    • 對新創建的對象添加實例變量(屬性)或相應的資源
  • 語法:
    class 類名(繼承列表):
    def init(self [,形參列表]):
    語句快

  • 說明:
    1. 初始化方法名必須為__init__不可變
    2. 初始化方法會在構造函數創建實例後自動調用,且將實例自身通過一個參數self傳入__init__方法
    3. 創造函數的實參將通過__init__方法的形參列表傳入__init__方法中
    4. 初始化方法內部如果需要返回則返回None
# 此實例示意__init__方法的自助調用以及添加實例變量
class Car:
    def __init__(self, c, b, m):
        print('__init__方法被調用')
        self.color = c # 顏色
        self.brand = b # 品牌
        self.model = m # 型號
    
    def run(self, speed):
        print(self.color, '的',
              self.brand, self.model,
              '正在以', speed, '公裏/小時的速度行駛!')
        
    def set_color(self, clr):
        '''此方法用來修改車的顏色信息'''
        self.color = clr

a4 = Car('紅色', '奧迪', 'A4')
# a4.__init__(.....) 顯示調用
print(a4.color)
a4.run(179)

a4.set_color('黑色')
a4.run(10)
__init__方法被調用
紅色
紅色 的 奧迪 A4 正在以 179 公裏/小時的速度行駛!
黑色 的 奧迪 A4 正在以 10 公裏/小時的速度行駛!

析構方法

  • 語法:
    class 類名(繼承列表):
    def del(self):
    語句塊

  • 說明:
    • 析構方法在對象銷毀時被自動調用
  • 作用:
    • 清理此對象占用的資源

Python不建議在析構方法內做任何事情,因為對象銷毀的時間難以確定

class Car:
    def __init__(self, name):
        self.name = name
        print('汽車', name, '對象已經創建!')
    
    def __del__(self):
        print(self.name, "對象已經銷毀")

c1 = Car('BYD E6')
c1 = Car('BMW x5')
汽車 BYD E6 對象已經創建!
BMW x5 對象已經銷毀
汽車 BMW x5 對象已經創建!
BYD E6 對象已經銷毀

預置實例屬性

  • __dict__ 屬性
    • 此屬性綁定一個儲存此實例自身實例變量的字典
class Dog:
    pass
print(dog1.__dict__)
dog1.kinds = '金毛'
print(dog1.__dict__)
{'kinds': '金毛', 'color': '黃色'}
{'kinds': '金毛', 'color': '黃色'}
  • __class__ 屬性
    • 此屬性綁定創建此實例的類
  • 作用:
    • 可以借助此屬性來訪問創建此實例的類
class Dog:
    pass
dog1 = Dog()
dog2 = Dog()
dog3 = dog1.__class__()
dog3.__class__ is Dog
True

面向對象的綜合示例

有兩個人:

    • 姓名:張三
    • 年齡:35
    • 姓名:李四
    • 年齡:38

行為:
1. 教別人學東西 teach
2. 賺錢
3. 借錢

事情:
- 張三 教 李四 學 Python
- 李四 教 張三 學 跳皮筋
- 張三 上班賺了 1000元
- 李四向張三借了200元

# 此示例示意如何用面向對象的方式創建對象,
# 並建立對象與對象之間的邏輯關系

class Human:
    '''人類,用於描述人的行為'''
    def __init__(self, n, a):
        self.name = n
        self.age = a
        self.money = 0
        
    def teach(self, other, skill):
        print(self.name, '教', other.name, '學', skill)
    
    def works(self, money):
        self.money += money
        print(self.name, '工作賺了', money, '元錢')
        
    def borrow(self, other, money):
        if other.money > money:
            print(other.name, '借給', self.name, money, '元錢')
            other.money -= money
            self.money += money
        else:
            print(other.name, '不借給', self.name)
    
    def show_info(self):
        print(self.age, '歲的', self.name, '存有', self.money, '元錢')

# 以下的類的使用
zhang3 = Human('張三', 35)
li4 = Human('李四', 8)
zhang3.teach(li4, 'Python')
li4.teach(zhang3, '跳皮筋')

zhang3.works(1000)
li4.borrow(zhang3, 200)
zhang3.show_info()
張三 教 李四 學 Python
李四 教 張三 學 跳皮筋
張三 工作賺了 1000 元錢
張三 借給 李四 200 元錢
35 歲的 張三 存有 800 元錢

用於類的函數

  • isinstance(obj, class_or_tuple)
    • 返回這個對象obj是否某個類class或某類的實例,如果是則返回True,否則返回Flase
    • type(obj) 返回對象類型
class Dog:
    pass
class Cat:
    pass
animal = Dog()
isinstance(animal, Dog) # T
isinstance(animal, Cat) # F
isinstance(animal, (Cat, int, list)) # F
isinstance(animal, (Cat, int, Dog)) # T
True

class attribute 類的變量

  • 類變量是類的屬性,此屬性屬於類

  • 作用:
    • 用來記錄類相關對的數據
  • 說明:
    • 類變量可以通過類直接訪問
    • 類變量可以通過類的實例直接訪問
    • 類變量可以通過此類的實例__class__屬性簡介訪問
# 此示例表示類變量的定義和使用
class Human:
    count = 0 # 創建一個類變量
    
print("Human的類變量count=", Human.count)
Human.count = 100
print("Human的類變量count=", Human.count)


class Human:
    count = 0
    
h1 = Human()
print("用h1對象訪問的類變量count=", h1.count)
h1.count = 100
print("用h1對象訪問的類變量count=", h1.count, "但是Human的類變量還是", Human.count)

h1.__class__.count += 1
print("用h1對象訪問的類變量還是count=", h1.count, "但是Human的類變量變了", Human.count)
Human的類變量count= 0
Human的類變量count= 100
用h1對象訪問的類變量count= 0
用h1對象訪問的類變量count= 100 但是Human的類變量還是 0
用h1對象訪問的類變量還是count= 100 但是Human的類變量變了 1
# 此示例示意用類變量來記錄對象的個數
class Car:
    count = 0 # 創建類變量,用來記錄汽車對象的總數
    def __init__(self, info):
        print(info, '被創建')
        self.data = info # 記錄傳入數據
        self.__class__.count += 1 # 讓車的總數加1
    
    def __del__(self):
        print(self.data, '被銷毀')
        self.__class__.count -= 1 # 當車被銷毀總數減1

b1 = Car("BYD")
b2 = Car("TTESLA")
b3 = Car("AUDI")
print("當前汽車總數是", Car.count)
del b3
print("當前汽車總數是", Car.count)
BYD 被創建
BYD 被銷毀
TTESLA 被創建
TTESLA 被銷毀
AUDI 被創建
當前汽車總數是 3
AUDI 被銷毀
當前汽車總數是 2

類的文檔字符串

  • 類內第一個沒有賦值給任何變量的字符串是類的文檔字符串

  • 說明:
    • 類的文檔字符串用類的 __doc__ 屬性可以訪問
    • 類的文檔字符串可以用help()函數查看
class Car:
    '''此類用來描述車的對象的行為
    這是Car類的文檔字符串'''
    def run(self, speed):
        '''車的run方法'''
        pass

help(Car)
Car.__doc__
Help on class Car in module __main__:

class Car(builtins.object)
 |  此類用來描述車的對象的行為
 |  這是Car類的文檔字符串
 |  
 |  Methods defined here:
 |  
 |  run(self, speed)
 |      車的run方法
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)






'此類用來描述車的對象的行為\n    這是Car類的文檔字符串'

類的__slots__列表

  • 作用:
    • 限定一個類的實例只能有固定的屬性(實例變量)
    • 通常為防止錯寫屬性名而發生運行時錯誤
  • 說明:
    • 含有__slots__列表的類創建的實例對象沒有__dict__屬性,即此實例不用字典來保存對象的屬性(實例變量)
# 此示例示意類的__slots__列表的作用
class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score

s1 = Student('小張', 58)
print(s1.score)
s1.socre = 100 # 此處錯寫了屬性名!但運行時不報錯!
print(s1.socre) # 這裏打印出了第三個屬性

class Student:
    __slots__ = ['name', 'score']
    def __init__(self, name, score):
        self.name = name
        self.score = score

s1 = Student('小張', 58)
print(s1.score)
s1.socre = 100 # 此處出錯,是因為已經用slots限定了變量
58
100
58



---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-19-5cac1bf3ae50> in <module>
     18 s1 = Student('小張', 58)
     19 print(s1.score)
---> 20 s1.socre = 100 # 此處錯寫了屬性名!但運行時不報錯!
     21 print(s1.socre) # 這裏打印出了第三個屬性


AttributeError: 'Student' object has no attribute 'socre'

@classmethod 類方法

  • 類方法是描述類的行為的方法,類方法屬於類

  • 說明:
    • 類方法需要用@classmethod裝飾器定義
    • 類方法至少有一個形參,第一個形參用於綁定類,預定寫為‘cls‘
    • 類和該類的實例都可以調用類方法
    • 類方法不能訪問此類創建的實例的屬性(只能訪問類變量)
# 此示例示意類方法的定義方法和用法
class Car:
    count = 0
    
    @classmethod
    def getTotalCount(cls):
        '''此方法為類方法,
        第一個參數為cls,代編調用此方法的類'''
        return cls.count
    
    @classmethod
    def updateCount(cls, number):
        cls.count += number

print(Car.getTotalCount()) # 用類來調用類方法
#Car.count += 1 # 面向對象思想不提倡直接操作屬性
Car.updateCount(1)
print(Car.getTotalCount()) 

c1 = Car()
c1.updateCount(100) # Car類的實例也可以調用類方法
print(c1.getTotalCount()) # 101
0
1

@staticmethod 靜態類方法

  • 靜態方法不屬於類,也不屬於類的實例,它相當於定義在類內普通函數,知識他的作用域屬於類
# 此示例示意靜態方法的創建和使用
class A:
    
    @staticmethod
    def myadd(x, y):
        '''此方法為靜態方法
        此方法的形參不需要傳入類或實例'''
        return x+y
    
print('1+2=', A.myadd(1, 2))
a = A()
print('100+200=', a.myadd(100, 200))
1+2= 3
100+200= 300

PythonOOP面向對象編程1