類和對象傻傻分不清?找不到“對象”迷迷糊糊?

  • 本講義適用於初學者,對類理解不了的,主要使用白話的方式講解類,高手自行略過

  • 本文主要用三個例子說明什麼是類,和類的繼承特性,理論知識請參考視頻,本文不做過多說明

  • 發揮想象力,發揮想象力,發揮想象力(重要的事說三遍)


什麼是類?

  • 類是一個抽象的概念,需要大夥發揮抽象思維,在世間萬物中,你把一個事物抽象出來,這就是類;你把這個事物具體化描述,這就是對象

  • 對象是類的實例化(具體描述)表現

現在,我們充分發揮想象力 整一個類先!

  • 例(我們打開LOL,雖然我很久沒玩了):

 

class Role(object):
    '''這是一個角色'''
    def __init__(self,name,物防,魔防,×××):
        self.名稱 = ''
        self.基礎物防 = ''
        self.基礎魔防 = ''
        self.基礎××× = ''

# ok,我們定義了一些簡單的屬性,類的一些數據,我們通常叫做屬性
    def hit(self,type,目標對象):
        '''這是一個普通×××'''
        damage = 0
        if type == '物理':
            # 有的英雄是物理普攻
            damage = self.基礎××× - 目標對象.物防
        elif type == '法術':
            # 有的是魔法×××
            damage = self.基礎××× - 目標對象.法防
        else:
            # 有的是混合×××
             damage = (self.基礎物攻*40% - 目標對象.法防) + (self.基礎魔攻*60% - 目標對象.法防)
        return danmage

    def walk(self,speed):
        # 這個角色不能走怎麼行?
        print(f'點一下走{speed}米')

# 好了,上述代碼在LOL啓動時候被執行,現在,3組的延凱選擇了蓋倫
# 嘿嘿,LOL馬上找到蓋倫的類,繼承這個角色

class 蓋倫(Role):
    # 英雄都是系統的角色
    # 趕快繼承Role
    def __init__(self,name,物防,魔防,×××):
        super(蓋倫,self).__init__(name,物防,魔防,×××) #新式繼承寫法
        self.物理××× = self.基礎××× + 皮膚加成 +各種加成


    def 致命打擊(self):
        key = 'Q'
        level = 1 #技能等級
        damage = 30 +1.4*self.物理×××
        return damage
# 先這樣,大招你自己想去
# LOL載入這個蓋倫
延凱 = 蓋倫(基礎屬性) # 蓋倫被實例化(對象)給延凱了!
# 嗯,一個人怎麼玩呢,現在小班選擇了寒冰射手
小班 = 寒冰射手(基礎屬性)
# 開始遊戲

。。。。

#一堆代碼在監測鼠標和鍵盤
if 延凱的鼠標點擊空地:
    延凱.walk(speed=350)
if 延凱的鼠標點擊小班:
    延凱.walk()
    延凱.walk()
    ....
    當延凱距離小班<100米:
        damage = 延凱.hit(type="物理",目標對象=小班)
        print("啊!延凱敲{目標對象.name}造成{damage}傷害")

#  上面是爲了你們理解類寫的僞代碼

老師,我不打遊戲,理解不了~

  • 那好,爲了你們的幸福,我再整一個類

  • 我不知道上面這個是誰

 

class People(object):
    '''我們都是人類!是人類'''
    def __init__(self,name,age,height)
        self.name = name
        self.age = age
        self.height = height

    def speak(self,word):
        print(f'{self.name}說:{word}')

class Girl(People):
    '''男人、女人、女博士,都是人,趕快繼承'''
    def __init__(self,name,age,height,三圍): # 女人嘛,要三圍
        super(Girl,self).__init__(name,age,height)
        self.三圍 = 三圍  # 我不知道怎麼寫這個三圍,將就看吧

    def 撒嬌(self,目標對象):
        print(f'{self.name}在對{目標對象}撒嬌')

    def 買買買(sefl):
        print('清空購物車')

# 這裏還有一個Boy類,自己去想吧
  • 程序員都苦逼,這天,我們3組的小賀找到一個女朋友

 

# 找到對象了,還不趕快實例化,不然女朋友跑了
小蒼 = Girl('小蒼',25,170,小蒼的三圍)
小賀 = Boy('小賀',28,180) # 男人要什麼三圍
# 有一天,小賀讓小蒼生氣了,不得了,小蒼直接....
小蒼.買買買()  # 調用方法,清空購物車,小賀得吃泡麪了~
# 小蒼買買買後,心情舒暢了,撩小賀中
小蒼.撒嬌(小賀)

# 好了,以上涉及人名如有侵權,請聯繫小班老師
  • 數據(名詞)=》屬性 ,動作(動詞)=》方法,類實例化=》對象

  • 騷年們,你們找到對象了嗎?


老師,我們都是技術宅,不懂遊戲,不懂對象,理解不了

  • 嗯,小編我再三思索,唯有此招


創建一個類微信公衆號操作類

  • 以下均爲僞代碼,不能實際部署

 

import configparser
class WeChat(object):
    '''這是一個操作微信公衆號的類'''
    def __init__(self):
        self.get_config()
        self.token = self.get_token # token在調用很多API都要有,這裏存儲起來
        # token在實際中還有時效性,需要判斷是否再次獲取

    def get_config(self):
        config = configparser.ConfigParser()
        config.read('config.ini')
        self.app_id = config['DEFAULT']['APPID'])
        self. secret = config['DEFAULT']['Secret'])

    def get_token(self):
        url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential'
        # 還記得爬蟲章節嗎?自己用request的get去拿token去~
        return token


    def send_all(self,content):
        # 羣發消息
        url = 'https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token=%s'%(self.token)
        # 自己去拼接URL
        value = {
            "filter":{
                "is_to_all":False, # True表示羣發,False不羣發
                "tag_id":0 # 如羣發,這裏可以不寫,否則,這個標識羣發的組ID
            },
            "text":{
                "content":content # 羣發內容
            },
            "msgtype":"text" # 羣發類型:文本
        }
        # 使用request的post方法,發送消息

#  一個簡單的微信操作類就寫完了
wc = WeChat()
content = '羣發消息測試'
wc.send_all(content)

與一個大型操作相關的,可以封裝爲一個類,方便類內部調用數據,方便類外部調用方法。

小結

  • 以上三個小栗子是否有助於你理解類呢?

  • 類,需要大家進行抽象;python世界,一切皆對象


我使用函數很簡單,爲什麼要寫類?

  • 這個問題,回到了前輩們的爭論:函數式編程好,還是面向對象好?

  • 這個沒有統一的答案,只能說,類的特性使它在編程中用的越來越廣泛

    • 安全性封裝,類的外部僅通過類的接口訪問,對於私有變量和方法有很好的保護

    • 現階段因爲代碼簡單,其實改寫類會耗費更多的時間,當程序複雜的時候,使用類的繼承特性、封裝特性,可以有效降低代碼量


類的一些拓展

類的私有屬性

self.__attrname用兩個下劃線開頭定義爲私有屬性,只在類的內部可以訪問

類的內置屬性

  • __dict__ : 返回這個類的屬性(包含一個字典,由類的數據屬性組成)

  • __doc__:類的文檔字符串

  • __name__: 返回類名

  • __module__: 類定義所在的模塊(類的全名是__main__.className,如果類位於一個導入模塊mymod中,那麼className.__module__等於mymod

  • __bases__: 類的所有父類構成元素(包含了一個由所有父類組成的元組)

只讀訪問私有屬性

  • 在類中定義一個方法返回此屬性,對外部提供只讀訪問接口

 

def get_attrname(self)
    return self.__attrname
  • 強制訪問(不要這麼做)
    實例後跟‘.’,接一個下劃線,接類名,接兩個下劃線的私有屬性

 

var1 = class_name()
var1._class_name__attrname

類的方法

  • 在類地內部,使用def關鍵字可以爲類定義一個方法,與一般函數定義不同,類方法必須包含參數self,且爲第一個參數

私有方法

  • 在類的內部使用,不開放給外部接口

  • __private_method兩個下劃線開頭,聲明該方法爲私有方法,不能在類地外部調用。在類的內部調用slef.__private_methods

一些特殊方法

  • __del__:析構函數(方法),在對象被銷燬時調用,常用於斷開連接、關閉文件等

  • __str__:設置此方法,需要設置其返回一個字符串,用於說明這個對象

靜態方法@staticmethod

  • 字段

    • 普通字段/普通屬性(保存在實例化的對象中)

    • 靜態字段/靜態方法(保存在類中)

  • 方法

    • 普通方法(保存在類中,實例化的對象進行調用,至少有一個self參數)

    • 靜態方法(保存在類中,調用者-》類(無需創建對象),可以有任意參數):

 

class F1:
    @staticmethod
    def a1(self):#靜態方法self參數不是必須
        print("F1A1")

F1.a1()直接調用,不必實例化。多用於一些功能、工具封裝的類

類方法 @classmethod

  • 不是很常用,請參照視頻7-4

  • 我們要寫一個只在類中運行而不在實例中運行的方法. 如果我們想讓方法不在實例中運行,可以這麼做

  • 這樣的好處是: 不管這個方式是從實例調用還是從類調用,它都用第一個參數把類傳遞過來.



作者簡介:


小寒


51CTO學院 Python微職位輔導老師



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章