pythonⅣ——面向對象

目錄

 

形參和實參

面向對象基本語法

類對象

類方法

靜態方法

鴨子類型

多態

繼承

單繼承-調用已重寫的父類方法

多繼承-調用已重寫的父類中的指定方法

init和繼承


形參和實參

# parameter 形參  argument 實參
# 實參類型:  位置實參  關鍵字實參(命名參數)
# 形參類型: 普通形參  默認形參(缺省參數)  可變形參(不定長參數)

# 默認形參: 可以形參設置默認值  設置實參則使用實參,不設置則使用默認值
# 默認形參必須在普通形參的後邊
# 關鍵字實參必須在位置實參的後邊
# def func1(num1, num2=10):
#     print(num1)
#     print(num2)
#
#
# func1(1)


"""可變形參: 元組型 和 字典型"""

# 元組型可變形參: 可以接收任意數量的位置實參
# 格式:  在形參前加* 表示該形參爲 元組型可變形參
# 機制:  可以將任意數量的位置實參包裝爲元組, 再賦值給可變形參args

# def func_sum(*args):  # args = (1, 2, 4, 5)
#     """求和函數"""
#     sum = 0
#     for num in args:
#         sum += num
#
#     print(sum)


# 需求: 接收任意數量參數進行求和
# func_sum(1, 2, 4, 5)
# func_sum(1, 2)


# 字典型可變形參: 可以接收任意數量的關鍵字實參
# 格式: 在形參前加** 表示該形參爲 字典型可變形參
# 機制: 可以將任意數量的關鍵字實參包裝爲字典, 再賦值給形參kwargs


# def save_userinfo(name, age, height, weight, gender):
def save_userinfo(name, **kwargs):
    print(name)
    print(kwargs)  # 字典
    # print(kwargs.get('age'))
    # print(kwargs.get('height'))


save_userinfo('張三', age=20)
save_userinfo('張三', height=1.7, weight=75, gender=True)

面向對象基本語法

class Fruits:  # 類名大駝峯

    def __init__(self, color, name):  # 使用場景:初始化
        self.color = color
        self.name = name

    def zd(self):  # self對應的實參是 調用該方法的對象(由解釋器自動設置);  使用場景:想在方法中使用對象自己的屬性
        print('我長大啦')
        print("我是:%s" % self.name)

    def __str__(self):
        return '顏色:%s,名字:%s' % (self.color, self.name)


apple = Fruits('紅紅', '蘋果')
apple.taste = '香甜可口'  # 屬性:首次賦值會定義,再次賦值修改;  這種定義屬性方式叫動態綁定
print("%s的%s" % (apple.color, apple.name))
print(apple.zd())

banana = Fruits('黃色', '香蕉')
print(banana.zd())

print(apple)


#   _xxx_(self):這類方法會在特定情況下自動調用,人稱 '魔法方法'
#       ● __init__(self):對象一創建完自動調用,用於初始化處理
#       ● __str__(self):自定義對象的打印;
#                     必須有返回值,返回的內容會代替默認的對象打印(默認打印對象內存地址)
#       ● __del__(self):對象銷燬前執行;
#                     1> 回收資源; 關閉文件、數據庫連接等;
#                     2> 用戶觀察對象的刪除情況(進行分析);
#                    ★對象   局部變量  方法結束時銷燬 ,執行_del_方法;
#                            全局變量  文件執行結束時 ,執行_del_方法;
#       ● __dict__(self):python編譯器內部會將私有屬性變量轉爲 '_類名和私有屬性名'的字符串拼接,然後進行操作,所以在外部直接進行修改是改不了的
#       ● 查看繼承鏈(方法查詢順序)  多繼承:
#                   1> 屬性: 類對象._mro_
#                   2> 方法: 類對象.mro()
#       ● __all__: 該變量可以控制 from 模塊 import * 導入的內容
#                   如果不把功能放到__all__變量列表中,那麼通過 ' from 模塊 import * '導入時,是不會被導入的
#       ● __name__: ❀ 無論採用哪種導入方式,都會將模塊中的代碼全部執行一遍
#                     當主動執行模塊文件時,__name__變量爲__name__
#                     當模塊被其他文件按導入時,__name__變量爲 模塊名
#                   if __name__ == '__main__':
#                         測試代碼

class Dog:
    def __init__(self):
        self.file = open('123.txt', 'w')
        print(self.file)

    def __del__(self):
        print('對象銷燬前回收')
        self.file.close()  # 對象刪除前將文件關閉,避免內存泄漏


# python中 數字(int、float)、字符串(str)、列表(list)、函數(function) 都是對象
tuple1 = (1,)
list1 = list(tuple1)  # 強轉 / 對象調用
print(type(list1))


# 私有屬性: __xx
#           只能在類內部使用
#          在類外部使用會報錯
#          即使強制在類外部賦值,私有屬性值也不會修改
class Dog:
    def __init__(self):
        self.file = open('123.txt', 'w')
        self.__count = 1

    def __del__(self):
        print('對象銷燬前回收', self.__count)
        self.file.close()  # 對象刪除前將文件關閉,避免內存泄漏(不及時釋放從而造成內存空間的浪費)


d = Dog()
d._Dog__count = 4
print(Dog.mro(), '.........', d._Dog__count)

# 私有方法:僅在類內部使用

類對象

"""
    類本身也是對象,稱爲類對象     類對象在定義類時自動創建
    類對象作用:
        1> 用於創建實例對象
        2> 記錄數據(類屬性)和執行操作(類方法)
    類屬性主要用於記錄一些類級別的數據

    實例對象和類屬性:
        類屬性可以被該類的所有對象所共有
        實例對象可以獲取類屬性,對象名.類屬性    但  不能修改,如果有同名的類屬性和實例屬性, 通過實例對象來獲取時, 優先獲取的是實例屬性

"""


class Dog:
    count = 0  # 定義類屬性,通過類對象來獲取/修改

    def __init__(self):
        Dog.count += 1


d1 = Dog()
d2 = Dog()
d2.count = 10   # 修改無用,反而是相當於是給d2這個實例對象新添了一個屬性
print(d2.count)
print(Dog.count)

類方法

# 類方法的使用場景:想要在方法中使用類屬性


class Dog:
    __count = 0  # 私有類屬性     get,set方法

    def __init__(self):
        Dog.__count += 1

    # def get_count(self):
    #     return Dog.__count

    @classmethod
    def get_count(cls):  # cls實參調用者類對象
        return cls.__count


# Dog()
# d = Dog()
# print(d.get_count())

Dog()
Dog()
print(Dog.get_count())

# 1> 類屬性定義:類內方法外
# 2> 類屬性只能通過類對象來修改
# 3> 實例對象只能獲取不能修改.
#     對象名.類屬性名 = 值, 該段代碼的含義是:
#        通過動態綁定的方式添加實例屬性,如果該實例本身就有該屬性的話就是對該實例屬性進行了一個修改
# 4> 如果不希望在類外邊通過類對象直接修改類屬性的值,可將該類屬性設爲私有
#    但 這樣的話,實例對象就獲取不到它的值了,可通過藉助方法來獲取
#    但 必須要創建實例對象,通過 實例對象來調用方法獲取,不想創建對象,可將方法設爲類方法,類方法通過 類對象或實例對象 都可以調用
# 5> 一般類屬性採用類進行調用,實例屬性用實例對象來調用
# 6> 實例方法必須有實例對象才能調用


靜態方法

class Dog:
    # 方法中 既不需要實例對象, 也不需要類對象時,爲了節省性能可將方法設爲靜態方法

    @staticmethod
    def eat():
        print('喝')


d = Dog()
d.eat()
Dog.eat()



# 靜態方法: 方法中既不使用實例對象(修改/獲取實例屬性, 調用其他實例方法), 也不使用類對象(修改/獲取類屬性, 調用其他的類方法)
#          定義靜態方法需要添加 @staticmethod, 對於參數沒有要求
#           類中的函數
# 類方法:  方法中使用類對象(修改/獲取類屬性, 調用其他的類方法)
#         定義類方法需要添加 @classmethod, 並且至少有一個參數,默認參數名爲cls, 代表調用該方法的類對象
# 實例方法:  方法中使用實例對象(修改/獲取實例屬性, 調用其他實例方法)
#           實例方法定義時,至少有一個參數,默認名爲self,代表調用該方法的實例對象

鴨子類型

# 動態語言沒有類型限制
# 設計模式是由於類型的限製造成的,所以python中是沒有設計模式的

class Meat:
    def __init__(self):
        self.name = '肉'


class Tudou:
    def __init__(self):
        self.name = '土豆'


def eat(meat):
    print('吃:%s' % meat.name)


eat(Meat())
eat(Tudou())

多態

# 多態: 讓同類的對象呈現多種表現形式(子類化)
#       方便項目代碼升級和重構

"""
    先繼承
    然後實現該'接口'方法
    父類的引用指向子類的對象,從而調用子類的實現類
"""


class Person:
    def dance(self):
        pass

    def play(self):
        self.dance()


class OldMan(Person):
    def dance(self):
        print('跳廣場舞')


class Baby(Person):
    def dance(self):
        print('蹦蹦跳')


OldMan().play()
Baby().play()

繼承

"""
    繼承:擁有父類的屬性和方法     系統方法是不會繼承的,比如:print()方法
    私有屬性和方法不被繼承,

"""


class Animal:
    def eat(self):
        print('吃')
    print('。。。。。。。')


class Dog(Animal):
    def bark(self):
        print('叫')

    print('*****')


class XTQ(Dog):  # 支持多層繼承
    pass


x = XTQ()
x.bark()
x.eat()

單繼承-調用已重寫的父類方法

class Dog:
    def bark(self):
        print('汪汪叫')


class XTQ(Dog):
    def bark(self):
        print('嗷嗷叫')

    def see_host(self):
        print('搖尾巴')
        # self.bark()  # 重寫了bark方法, 調用的一定是自己的bark方法

        # 需求: 調用父類的bark方法 (調用被重寫的方法)   三種語法
        # 語法1  父類.方法名(對象)
        Dog.bark(self)

        # 語法2 super(當前類, 對象).方法名()
        # super(XTQ, self).bark()

        # 語法3 super().方法名()   語法2的簡化形式    使用率最高
        # super().bark()


xtq = XTQ()
xtq.see_host()
print(XTQ.__dict__)

多繼承-調用已重寫的父類中的指定方法

class God:
    def eat(self):
        print('吃蟠桃')

    def drink(self):
        print('喝水')


class Dog:
    def eat(self):
        print('吃粑粑')

    def drink(self):
        print('喝牛奶')


class XTQ(Dog, God):
    # 需求:想要吃蟠桃 喝牛奶
    # 分析:此時,就不能通過改動繼承順序(繼承鏈),改變順序治標不治本
    # 解決方式:1> 重寫
    #          2> 在重寫的方法中調用父類的方法(調用被重寫的方法)    父類.方法名(對象)
    def eat_drink(self):
        """
            此種寫法調用的方法是 Dog對象類中的方法(因爲本身沒有,然後調用第一個父類Dog中的方法)
            self.eat()
            self.drink()
        """
        '''指定調用'''
        God.eat(self)
        Dog.drink(self)

        # 這種方式會從指定類在繼承鏈中的下一個類開始查詢
        # super(Dog, self).eat()  # 多繼承情況下不建議使用


x = XTQ()
x.eat_drink()

# 查看繼承鏈(方法查詢順序)
print(XTQ.mro())    # 類對象調用方法
print(XTQ.__mro__)


init和繼承

class Animal(object):
    def __init__(self):     # 此時的self == Cat的實例對象tom
        self.name = "Tom"


class Cat(Animal):
    def __init__(self):
        # 一旦重寫了init方法, 父類的init方法將不會調用, 父類定義的屬性也不會繼承
        # 這種情況下, 想要繼承父類的屬性, 需要手動調用父類的init方法 (調用被重寫的方法)
        Animal.__init__(self)   # super().__init__(),相較而言,Animal.__init__(self)更好理解些
        self.color = "red"

    def __str__(self):
        return "my name is %s,my color is %s" % (self.name, self.color)


tom = Cat()
print(tom)

print('❀-------------------------')


class Dog:
    def __init__(self, type):
        self.type = type


class XTQ(Dog):
    def __init__(self, type):
        # super().__init__(type)
        Dog.__init__(self, type)    # 此方式必須要傳兩個參數
        self.color = '黑'


xtq = XTQ('天狗')
print(xtq.type)


print('❀-------------------------')


class Dog:
    def __init__(self, type_arg):
        self.type = type_arg
        print(type(self))  # 獲取對象類型


class XTQ(Dog):
    def __init__(self, type):

        # 調用父類的init方法( ★繼承屬性 )
        Dog.__init__(self, type)

        self.color = '黑'


# dog1 = Dog('狗')  # 打印的對象類型爲Dog
xtq = XTQ('天狗')  # 打印的對象類型爲XTQ

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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