1. 程式人生 > >Python全棧學習筆記day 22:初試面向物件、類

Python全棧學習筆記day 22:初試面向物件、類

一、面向過程 VS 面向物件 

面向過程:

面向過程的程式設計的核心是過程(流水線式思維)

優點是:極大的降低了寫程式的複雜度,只需要順著要執行的步驟,堆疊程式碼即可。

缺點是:一套流水線或者流程就是用來解決一個問題,程式碼牽一髮而動全身。

面向物件:

面向物件的程式設計的核心是物件(上帝式思維)

優點是:解決了程式的擴充套件性。對某一個物件單獨修改,會立刻反映到整個體系中,如對遊戲中一個人物引數的特徵和技能修改都很容易。

缺點:可控性差,無法向面向過程的程式設計流水線式的可以很精準的預測問題的處理流程與結果,面向物件的程式一旦開始就由物件之間的互動解決問題

即便是上帝也無法預測最終結果。於是我們經常看到一個遊戲人某一引數的修改極有可能導致陰霸的技能出現,一刀砍死3個人,這個遊戲就失去平衡。

二、類和物件

'''
class 類名:
    '類的文件字串'
    類體
'''

#我們建立一個類
class Data:
    pass

 

一:我們定義的類的屬性到底存到哪裡了?有兩種方式檢視
dir(類名):查出的是一個名字列表
類名.__dict__:查出的是一個字典,key為屬性名,value為屬性值

二:特殊的類屬性
類名.__name__# 類的名字(字串)
類名.__doc__# 類的文件字串
類名.__base__# 類的第一個父類(在講繼承時會講)
類名.__bases__# 類所有父類構成的元組(在講繼承時會講)
類名.__dict__# 類的字典屬性
類名.__module__# 類定義所在的模組
類名.__class__# 例項對應的類(僅新式類中)
 物件 = 類名()
 過程:
     類名() 首先 會創造出一個物件,建立了一個self變數
     呼叫init方法,類名括號裡的引數會被這裡接收
     執行init方法
     返回self
 物件能做的事:
     檢視屬性
     呼叫方法
     __dict__ 對於物件的增刪改查操作都可以通過字典的語法進行
 類名能做的事:
     例項化
     呼叫方法 : 只不過要自己傳遞self引數
     呼叫類中的屬性,也就是呼叫靜態屬性
     __dict__ 對於類中的名字只能看 不能操作

栗子:
class Person:                 # 類名
    country = 'China'         # 創造了一個只要是這個類就一定有的屬性
                               # 類屬性 靜態屬性
    def __init__(self,*args):  # 初始化方法,self是物件,是一個必須傳的引數
        # self就是一個可以儲存很多屬性的大字典
        self.name = args[0]   # 往字典裡新增屬性的方式發生了一些變化
        self.hp = args[1]
        self.aggr = args[2]
        self.sex = args[3]

    def walk(self,n):         # 方法,一般情況下必須傳self引數,且必須寫在第一個
                              # 後面還可以傳其他引數,是自由的
        print('%s走走走,走了%s步'%(self.name,n))

print(Person.country)        # 類名 可以檢視類中的屬性,不需要例項化就可以檢視
alex = Person('狗剩兒',100,1,'不詳')  # 類名還可以例項化物件,alex物件   # 例項化
print(alex.__dict__) # 檢視所有屬性
print(alex.name)  # 檢視屬性值
print(alex.hp)  # 檢視屬性值
alex.walk(5)    # Person.walk(alex,5)  # 呼叫方法 類名.方法名(物件名)

 

栗子:人狗大戰

def Dog(name,blood,aggr,kind):
    dog = {
        'name': name,
        'blood': blood,  # 血量
        'aggr': aggr,  # 攻擊力
        'kind': kind,
    }
    def bite(person):
        person['blood'] -= dog['aggr']
        print('%s被咬了,掉了%s的血' % (person['name'], dog['aggr']))
    dog['bite'] = bite
    return dog

def Person(name,blood,aggr,sex):
    person = {
        'name' : name,
        'blood': blood,   # 血量
        'aggr': aggr,      # 攻擊力
        'sex':sex,
    }
    def attack(dog):
        dog['blood'] -= person['aggr']
        print('%s被打了,掉了%s的血' % (dog['name'], person['aggr']))
    person['attack'] = attack
    return person

# 程式碼精簡了 方便增加人物 方便修改 人物更加規範  —— 人模子



jin = Dog('金老闆',1000,100,'teddy')
alex = Person('狗剩兒',100,1,'不詳')
# nezha = Person('哪吒',200,2,'不詳')
print(jin)
jin['bite'](alex)
alex['attack'](jin)

Dog函式和Person函式 都是定義了一類事物
直到呼叫了函式,賦值了之後才真的有了一個實實在在的人或狗


面向物件程式設計:
所謂模子 就是 類 抽象的 我能知道有什麼屬性 有什麼技能 但不能知道屬性具體的值
jin alex nezha 就是物件 有具體的值,屬性和技能都是根據類規範的

加強版人狗大戰:

定義一個人類:

class Person:  # 定義一個人類
    role = 'person'   人的角色屬性都是人

    def __init__(self, name, aggressivity, life_value, money):
        self.name = name                       每一個角色都有自己的暱稱;
        self.aggressivity = aggressivity       每一個角色都有自己的攻擊力;
        self.life_value = life_value           每一個角色都有自己的生命值;
        self.money = money

    def attack(self,dog):
         人可以攻擊狗,這裡的狗也是一個物件。
         人攻擊狗,那麼狗的生命值就會根據人的攻擊力而下降
        dog.life_value -= self.aggressivity

定義一個狗類:

class Dog:  # 定義一個狗類
    role = 'dog'       狗的角色屬性都是狗

    def __init__(self, name, breed, aggressivity, life_value):
        self.name = name                         每一隻狗都有自己的暱稱;
        self.breed = breed                       每一隻狗都有自己的品種;
        self.aggressivity = aggressivity           每一隻狗都有自己的攻擊力;
        self.life_value = life_value               每一隻狗都有自己的生命值;

    def bite(self,people):
                 狗可以咬人,這裡的狗也是一個物件。
                 狗咬人,那麼人的生命值就會根據狗的攻擊力而下降
        people.life_value -= self.aggressivity

又建立一個新的兵器類:

class Weapon:
    def __init__(self,name, price, aggrev, life_value):
        self.name = name
        self.price = price
        self.aggrev = aggrev
        self.life_value = life_value

    def update(self, obj):                       obj就是要帶這個裝備的人
        obj.money -= self.price                  用這個武器的人花錢買所以對應的錢要減少
        obj.aggressivity += self.aggrev          帶上這個裝備可以讓人增加攻擊
        obj.life_value += self.life_value        帶上這個裝備可以讓人增加生命值

    def prick(self, obj):                       這是該裝備的主動技能,扎死對方
        obj.life_value -= 500                   假設攻擊力是500

測試互動 :

lance = Weapon('長矛',200,6,100)
egg = Person('egon',10,1000,600)             創造了一個實實在在的人egg
ha2 = Dog('二愣子','哈士奇',10,1000)          創造了一隻實實在在的狗ha2

egg獨自力戰"二愣子"深感吃力,決定窮畢生積蓄買一把武器

if egg.money > lance.price:                 如果egg的錢比裝備的價格多,可以買一把長矛
    lance.update(egg)                       egg花錢買了一個長矛防身,且自身屬性得到了提高
    egg.weapon = lance                      egg裝備上了長矛

print(egg.money,egg.life_value,egg.aggressivity)

print(ha2.life_value)
egg.attack(ha2)                       egg打了ha2一下
print(ha2.life_value)
egg.weapon.prick(ha2)                 發動武器技能
print(ha2.life_value)                 ha2不敵狡猾的人類用武器取勝,血槽空了一半

 

類有兩種屬性:靜態屬性和動態屬性

  • 靜態屬性就是直接在類中定義的變數
  • 動態屬性就是定義在類中的方法