目錄
形參和實參
# 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