1. 程式人生 > >Python基礎筆記_Day10_Python面向物件、類和物件、__init__、__str__、訪問限制、set、get

Python基礎筆記_Day10_Python面向物件、類和物件、__init__、__str__、訪問限制、set、get

Day10_Python面向物件、類和物件、initstr、訪問限制、set、get

10.01_Python語言基礎(面向物件思想)(理解)
10.02_Python語言基礎(類和物件)(掌握)
10.03_Python語言基礎(類的構成)(掌握)
10.04_Python語言基礎(類的抽象)(掌握)
10.05_Python語言基礎(定義類)(掌握)
10.06_Python語言基礎(經典類和新式類)(熟練)
10.07_Python語言基礎(建立物件)(掌握)
10.08_Python語言基礎(__init__方法和self的作用)(掌握)
10.09_Python語言基礎(__del__()方法(析構方法))(熟練)
10.10_Python語言基礎(建立多個物件)(掌握)
10.11_Python語言基礎(魔方方法)(掌握)
10.12_Python語言基礎(__str__和__repr__())(掌握)
10.13_Python語言基礎(構造方法)(掌握)
10.14_Python語言基礎(重寫__init__()和__str__()方法)(掌握)
10.15_Python語言基礎(理解self)(掌握)
10.16_Python語言基礎(應用-烤牛排)(掌握)
10.17_Python語言基礎(訪問限制)(掌握)
10.18_Python語言基礎(set()和get()方法)(掌握)
10.19_Python語言基礎(複習今天的內容)(掌握)

10.01_Python語言基礎(面向物件思想)(理解)

面向物件的思想

思考:
   請用程式描述如下事件:
      A同學報道等級資訊
      B同學報道等級資訊
      C同學報道等級資訊
      A同學做自我介紹
      B同學自我介紹
      c同學自我介紹

"""
請用程式描述如下事件:
      A同學報道等級資訊
      B同學報道等級資訊
      C同學報道等級資訊
      A同學做自我介紹
      B同學自我介紹
      c同學自我介紹
"""
stu_a = {"name":"A","age":21}
stu_b = {"name":"B","age":22}
stu_c = {"name":"C","age":23}

def stu_infor(stu):
    for key,value in stu.items():
        print("key = %s,value = %d"%(key,value))

"""

面向過程:
根據業務邏輯從上到下寫程式碼

面向物件:
將資料與函式繫結到一起,進行封裝,能夠更快速的開發程式,減少程式碼的重寫的過程

def 傳送郵件(內容):
    # 連線郵箱伺服器
    # 傳送郵件
    # 關閉連線

10.02_Python語言基礎(類和物件)(掌握)

  • 類和物件的概述

物件和類

物件是面向物件思想的核心
在使用物件的過程中,為了將具有共同特徵和行為的一組物件抽象定義-----》類
類---》製造飛機的圖紙
用它來建立的飛機就相當於物件

具有相似的內部狀態和運動規律的實體的集合(抽象)
或者具有相同的屬性和行為的統稱

定義:
  類  抽象的  在使用的時候通常會找到這個類的具體的存在----》物件
  特點:
     使用這個具體的存在,一個類可以找到多個物件,一個類可以建立多個物件

物件

概述:
   某一個具體事物的存在,在現實世界中可以看得見摸得著
可以直接使用

總結:
  類和物件之間的關係:
     就像利用玩具模型來建立多種不同的玩具
     類就是建立物件的模板

區分類和物件

賓士汽車   	類
賓士smart   	類
張三的那輛賓士smart    物件

狗    類
大黃狗   類
李四家的那隻大黃狗    物件

水果    類
蘋果   類
紅蘋果   類   紅富士蘋果   類
張三嘴裡吃了一半的蘋果   物件

10.03_Python語言基礎(類的構成)(掌握)

類的構成

類(class):由3部分組成
類的名稱:類名
類的屬性:一組資料
類的方法:允許對其操作的方法(行為)

設計一個人類

"""
事物的名稱(類名):人(Person)
屬性:身高  年齡
方法(行為):跑,吃飯

"""
"""
狗  類
類名:dog
屬性:品種,毛色,性別,腿的數量
方法:叫,跑,咬人,搖尾巴
"""

10.04_Python語言基礎(類的抽象)(掌握)

如何把日常生活中的事物抽象成程式中的類?

類:
    擁有相同屬性和行為的物件可以抽取出來-----》類
    
一般名稱提煉法
例如:
 1.坦克發射了3顆炮彈炸掉了2架飛機
 坦克----》抽象成類
 炮彈---》抽象成類
 飛機----》抽象成類
 
 2.小明在公車上牽了一條叼著熱狗的狗
 小明  -----》	人類
 公車  -----》	交通工具類
 熱狗  -----》	食物類
 狗    -----》	狗類

遊戲中的類和物件

cf
人
槍

植物大戰殭屍:
向日葵   -----》類
    類名:xrk
    屬性:顏色,尺寸
    行為:產生陽光
    
豌豆:   ------》   類
    類名:  wd
    屬性:顏色,髮型
    行為:發射炮彈  
殭屍:
    類名:js
    屬性:顏色,
    行為:走,吃植物,啃

10.05_Python語言基礎(定義類)(掌握)

定義一個類的格式:

class 類名:
	屬性1
	屬性2
	屬性3
	... ...

	方法1
	方法2
	方法3
	... ...

定義類–貓

"""
貓:
   類名:cat
   屬性:毛色,性別
   行為:跑,吃
"""
class Cat:
    #屬性

    #方法
    def eat(self):
        print("貓吃魚....")

    def drink(self):
        print("貓喝可樂....")

定義類–車

"""
車:
   類名:Car
   屬性:顏色,
   行為:跑
"""
class Car:
    #方法列表
    def getCarInfo(self):
        print("車的輪子數:%d,顏色%s"%())

    def move(self):
        print("車子在移動....")

10.06_Python語言基礎(經典類和新式類)(熟練)

新式類:
* Python2.2引入了新式類
* Python3.X之後預設都是新式類,採用了C3演算法,__MRO__可以檢視繼承順序
* 在類名後面(object),Car(object)

  • 說明:
    • 定義類的時候有兩種,新式類和經典類,上面定義Car為經典類
    • 如class Car(object): 是新式類
    • class Cat: 是經典類

注意:
定義類名時,儘量使用大駝峰命名法則


10.07_Python語言基礎(建立物件)(掌握)

python中,可以根據已經定義好的類來建立一個一個的物件

  • 建立物件的格式:物件名 = 類名()

建立一個Car類

#建立一個Car類
class Car(object):
    def move(self):
        print("車子在移動....")
    def toot(self):
        print("車子在鳴笛....")


#建立車子的物件,並用變數進行儲存
BMW = Car()
BMW.color = "黑色"#車子的顏色
BMW.wheelNum = 4#車輪的數量
BMW.color = "白色"
BMW.move()
BMW.toot()
print(BMW.color)
print(BMW.wheelNum)

總結:
BMW = Car():這樣就產生了一個Car的例項物件,
此時可以通過例項物件BMW訪問屬性和行為
BMW—>物件,它擁有屬性和行為

為物件新增屬性

  • 下面以Cat類為例子,新增屬性

class Cat:
    def eat(self):
        print("貓在吃魚.....")
    def drink(self):
        print("貓在和芬達....")
        
#建立一個Cat物件
tom = Cat()
#呼叫tom指向的物件中的方法
tom.eat()
tom.drink()
tom.name = "湯姆"
tom.age = 3

獲取物件的屬性
class Cat:
def eat(self):
print(“貓在吃魚…”)
def drink(self):
print(“貓在和芬達…”)

#建立一個Cat物件
tom = Cat()
#呼叫tom指向的物件中的方法
tom.eat()
tom.drink()
tom.name = "湯姆"
tom.age = 3
print("tom的中文名:%s,年齡:%d"%(tom.name,tom.age))

10.08_Python語言基礎(__init__方法和self的作用)(掌握)

init方法是初始化函式,用來完成一些物件預設的設定

  • init方法格式

class 類名:
     #初始化函式,用來完成一些預設的設定
     def __init__(self):
            函式體語句
  • init()方法呼叫
    • 下面以汽車類Car示例init方法的呼叫

# 第一種方式

class Car:
    # 初始化方法
    def __init__(self):
        self.color = "黑色"
        self.wheelNum = 4

    # 普通的方法,移動
    def move(self):
        print("車子在移動.....")


# 建立物件
bmw = Car()
print("車子的顏色:%s" % bmw.color)
print("車子的輪子數:%d" % bmw.wheelNum)
bmw1 = Car()
print("車子的顏色:%s" % bmw1.color)
print("車子的輪子數:%d" % bmw1.wheelNum)

總結:
當建立Car物件後,在沒有呼叫__init__()函式的前提下,
bmw就預設擁有了兩個屬性color/wheelNum,
原因是__init__()函式在建立物件後,就立刻預設被呼叫


  • 還有另一種方式能更靈活的使用init方法

#第二種方式

	class Car:
	    #初始化方法
	    def __init__(self,newWheelNum,newColor):
	        self.wheelNum = newWheelNum
	        self.color = newColor
	    #普通的方法,移動
	    def move(self):
	        print("車子在移動.....")
	#建立物件
	bmw = Car(4,"黃色")
	print("車子的顏色:%s"%bmw.color)
	print("車子的輪子數:%d"%bmw.wheelNum)
	bmw1 = Car(6,"綠色")
	print("車子的顏色:%s"%bmw1.color)
	print("車子的輪子數:%d"%bmw1.wheelNum)

總結:
init():在建立一個物件的時候預設被呼叫,不需要手動呼叫
init(self),預設一個引數名字為self,不需要開發者傳遞
python 直譯器會自動將當前的物件的引用傳遞進來


10.09_Python語言基礎(del()方法(析構方法))(熟練)

  • 建立物件後,python直譯器預設呼叫__init__()
  • 當刪除一個物件的時候,python直譯器也會預設呼叫__del__()

分析下面案例
import sys

class Cat(object):
    def __init__(self):
        self.color = "while"
        self.weight = "8斤"

    def __del__(self):
        print("所有物件被幹掉啦")

    def __str__(self):
        return ("顏色%s-體重%s" % (self.color, self.weight))


Tom01 = Cat()
print("Tom01即將被幹掉,當前Tom01引用指向地址被引用數量%s" % sys.getrefcount(Tom01))
Tom02 = Tom01
Tom03 = Tom02
print(Tom01)
print(Tom02)
print(Tom03)

print("Tom01即將被幹掉,當前Tom01引用指向地址被引用數量%s" % sys.getrefcount(Cat))
print(id(Cat))
del Tom01

print("Tom02即將被幹掉,當前Tom02引用指向地址被引用數量%s" % sys.getrefcount(Tom02))
print("Tom02即將被幹掉,當前Tom03引用指向地址被引用數量%s" % sys.getrefcount(Tom03))
print("Tom02和Tom03引用指向地址是相同的嗎?", Tom02 == Tom03)
del Tom02
print("Tom02被幹掉啦")

# del Tom03
# print("Tom03被幹掉啦")
print("我是程式結尾的一句話")
print("-" * 30)

print(Tom03)
print(repr(Tom03))
print(eval(repr(Tom03)))
  • 總結
    • 當有1個變數儲存了物件的引用,此時物件的引用計數加1
    • 當使用__del__()函式的時候,刪除的是變數指向的物件時,
    • 如果物件的引用計數不為1,比如3,那麼此時只會讓這個引用計數減1
    • 即變為2,當再次呼叫del 此時會通用刪除引用計數,直到變數的引用計數為0
    • 此時才會將變數指向的物件真正刪除
    • 獲取物件計數:sys.getrefcount(object))

10.10_Python語言基礎(建立多個物件)(掌握)

同一個類可以建立多個物件,比如常見的貓有加菲和Tom

class Cat:
    def eat(self):
        print("貓吃魚....")
    def drink(self):
        print("貓喝水....")
  
#建立tom 物件       
tom = Cat()
tom.eat()
tom.drink()
#給tom指向的物件新增兩個屬性
tom.name = "湯姆"
tom.age = 2


jiafei = Cat()
jiafei.eat()
jiafei.drink()
jiafei.name = "加菲"
jiafei.age = 3

同一個類建立的多個物件是相互獨立的

10.11_Python語言基礎(魔方方法)(掌握)

  • 魔方方法:
    • 魔法方法是Python中的特殊方法
    • 魔方方法是指指被包含下劃線的方法或者所能呼叫的方法的統稱
    • 這些統方法在特殊的情況下被呼叫,並且基本沒有手動呼叫它的必要

下面我們看一下使用Cat類編寫的案例
#定義類
class Car:
def init(self,newWheelNum,newColor):
self.wheelNum = newWheelNum
self.color = newColor

    def __str__(self):
        msg = "嘿嘿....我的顏色是"+self.color+"我有"+self.wheelNum+"個輪子"
        return msg

    def move(self):

        print("車子在移動....")

#建立一個物件
bmw = Car("4","白色")
print(bmw)

總結:
在python中方法名如果是__XXX__那麼就具有特殊的功能,—》魔方
str():
當使用print輸出物件,只要定義了__str__()方法,
那麼就會返回這個方法中return 的資料


10.12_Python語言基礎(str__和__repr())(掌握)

  • str__和__repr()
    • repr()與__str__()函式的功能類似
    • str()用於將數值轉化為人閱讀的形式
    • repr()轉化為python直譯器讀取的形式

str():在呼叫print列印物件的時候自動呼叫,給使用者用的,是一個描述物件的方法
repr():給機器用的,供python的直譯器讀取

注意:
在沒有__str__()函式時,有__repr__(),str == repr

import datetime

now = datetime.datetime.now()
print(str(now))
print(repr(now))
print(eval(repr(now)))

說明:
datetime python的內建模組,import 載入匯入模組
now = datetime.datetime.now()系統當前的時間賦值給now變數
eval函式是把引數當做程式碼執行,驗證repr之後的字串可以被python識別執行


class Person(object):
    def __init__(self,name,age,height,weight):
        self.name = name
        self.age = age
        self.height = height
        self.weight = weight
    def __str__(self):
        return "%s-%d-%d-%d"%(self.name,self.age,self.height,self.weight)

#建立人的物件
per = Person("hanmeimei",20,170,55)

print(per)
print(repr(per))
# print(eval(repr(per)))#eval函式中的引數為一個字串,如果不是一個字串會報錯
aa = "hello"
print(repr(aa))
print(eval(repr(aa)))

優點:
當一個物件的屬性過多,並且還要列印,重寫__str__()方法簡化程式碼的書寫
可讀性強


注意:
repr()函式得到的字串,通常可以用來獲得該物件,obj == eval(repr(obj))這個等式是成立的
返回的是一個字串


10.13_Python語言基礎(構造方法)(掌握)

  • 定義:
    • 構造方法類似__init__()函式,差別在於一個物件被構建好之後會自定呼叫該方法
    • python中建立一個構造方法(使用__init__())

class Cat:
	def __init__(self):
         初始化屬性

10.14_Python語言基礎(重寫__init__()和__str__()方法)(掌握)

  • 概述:
    • Python中所有的類都直接或間接繼承object
    • object中有__init__()和__str__()方法
    • object中的這兩個方法大部分時間和我們使用時的需求不匹配
    • 我們可以根據自己的需求對方法體進行更改,這就叫做重寫
    • 更多內容在明天的知識點繼承中
  • 重寫方法使用總結:
    • 當兩個關聯的類,出現了相同的函式名,在呼叫該函式時,先在本類中找,
    • 如果有,呼叫
    • 如果沒有,在去父類找,如果有呼叫,
    • 如果沒有,去基類,找不到報錯

重寫對於類很重要:
尤其對於構造 init


class Bird():
    def __init__(self):
        self.hungry = True

    def eat(self):
        if self.hungry:
            print(".....")
            self.hungry = False
        else:
            print("no thanks")
b = Bird()
b.eat()
b.eat()

重寫的定義:
在子類中定義了一個和父類同名的函式—》重寫


10.15_Python語言基礎(理解self)(掌握)

#定義一個類
class Animal:
    def __init__(self,name):
        self.name = name
    def printName(self):
        print("名字為:%s"%self.name)

#定義一個函式
def myPrint(animal):
    animal.printName()

#建立物件
dog1 = Animal("西西")
myPrint(dog1)

dog2 = Animal("北北")
myPrint(dog2)
  • 總結:
    * 所謂self理解為自己,也就是物件自身
    * 程式中的self是什麼?哪個物件呼叫了__init__(),self就代表誰

10.16_Python語言基礎(應用-烤牛排)(掌握)

"""
烤牛排:
類:
    類名:
        牛排:
    屬性:
        幾成熟
            0--3表示生的,4--6表示半生不熟,7--9表示熟了,10及以上表示糊了
        紅酒
        胡椒
        ... ...
    行為:
        燒烤時間
        新增佐料
        __init__()
        __str__()

	"""


class CookSteak:
    def __init__(self):
        self.time = 0
        self.cook_level = 0
        self.cook_string = "生的"
        self.condiments = []

    def cook(self, time):
        self.cook_level += time
        if self.cook_level > 9:
            self.cook_string = "扔了吧,都糊啦"
        elif self.cook_level > 6:
            self.cook_string = "熟了,味道應該很棒"
        elif self.cook_level > 3:
            self.cook_string = "半生不熟,快要熟了"
        elif self.cook_level > 0:
            self.cook_string = "牛排剛放進去,耐性等一會"
        else:
            print("沒有這個狀態")
        print("牛排已經烤了很久了,現在達到%s成熟了," % self.cook_level)

    def add_cendiments(self, cendiments):
        self.condiments.append(cendiments)

    def __str__(self):
        return "牛排已經烤了很久了,現在達到%s成熟了,新增的佐料有%s" % (self.cook_level, self.condiments)


hui_ling_dun = CookSteak()
hui_ling_dun.cook(1)
hui_ling_dun.cook(1)
hui_ling_dun.cook(1)
hui_ling_dun.cook(1)
hui_ling_dun.add_cendiments("胡椒粉")
hui_ling_dun.cook(1)
hui_ling_dun.cook(1)
hui_ling_dun.add_cendiments("紅酒")
hui_ling_dun.cook(1)
print(hui_ling_dun)

10.17_Python語言基礎(訪問限制)(掌握)

  • 如果有一個物件,當需要對其進行修改屬性:
    • 方法2種
    • #直接修改 物件名.屬性名 = 資料
    • #間接修改 物件名.方法名()

 將屬性定義為私有
 格式:
 __屬性名

屬性私有案例

# 定義一個類
class Person(object):
    def __init__(self, name):
        self.__name = name

    def __str__(self):
        return self.__name

    def getName(self):
        return self.__name

    def setName(self, newName):
        if len(newName) <= 5:
            self.__name = newName
        else:
            print("名字的長度需要小於等於5")


person = Person("張三")
# print(person)
# #直接修改   物件名.屬性名 = 資料
# person.__name = "李四"
# print(person)

# 間接訪問   物件名.屬性名
# print(person.__name)  #報錯


person.setName("李四")
print(person.getName())

person.setName("王五")
print(person.getName())
  • python沒有c++或者Java中的public(公有) private(私有)區分公有和私有
  • python以屬性的命名方式來進行區分:
    • 如果在屬性名前面加上兩個下劃線“__”,則表明該屬性是私有屬性
    • 否則就是公有屬性(方法的設定同屬性設定一致)

其實,Python並沒有真正的私有化支援,但可用下劃線得到偽私有。   
儘量避免定義以下劃線開頭的變數!
(1)_xxx      "單下劃線 " 開始的成員變數叫做保護變數,
	意思是隻有類例項和子類例項能訪問到這些變數,
	需通過類提供的介面進行訪問;不能用'from module import *'匯入
(2)__xxx    類中的私有變數/方法名 (Python的函式也是物件,
	所以成員方法稱為成員變數也行得通。),
	" 雙下劃線 " 開始的是私有成員,意思是隻有類物件自己能訪問,連子類物件也不能訪問到這個資料。
(3)__xxx__ 系統定義名字,前後均有一個“雙下劃線” 代表python裡特殊方法專用的標識,
	如 __init__()代表類的建構函式。

10.18_Python語言基礎(set()和get()方法)(掌握)

  • Python私有屬性修改
    • 類中的屬性私有化之後,外部無法訪問
    • 我們可以在類中定義公共的方法提供給外部,讓這個公共的方在類內部修改私有屬性
      set()和get()使用案例:

class Person(object):
    def __init__(self,name,age,height,weight,money):
        self.name = name
        self.__age__ = age
        self.height = height
        self.weight = weight
        self.__money = money

    def ss(self):
        print(self.__money)

    #通過內部的方法,去修改私有屬性
    #通過自定義的方法實現對私有屬性的修改
    def getMoney(self):
        return self.__money
    def setMoney(self,money):
        #資料的過濾
        if money < 0:
            money = 0
        self.__money = money

#建立物件
person = Person("張三",12,170,55,100)
# person.age = 15
# person.setMoney(200)
# print(person.getMoney())

# print(person.__money)#外部使用  不ok
print(person.ss)#內部  ok

思考,不能通過物件訪問私有屬性?
在python的直譯器把__money 變成_Person_money.
任然可以使用_Person_money去訪問,但是不建議這麼做,


"""
person._Person__money = 1
print(person.getMoney())

print(person.__age__)
"""
在python中__XXX__,屬於特殊的變數,可以直接訪問(公有)
"""

10.19_Python語言基礎(複習今天的內容)(掌握)