Python基础_Day13
生活随笔
收集整理的這篇文章主要介紹了
Python基础_Day13
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.聽寫
借助封裝和繼承 Tiger(老虎)屬性:品種 年齡 性別行為:吃飯 Cat(貓)屬性:昵稱 品種 年齡 性別行為:吃飯 爬樹 創建對象:東北虎 2 雌---調用吃飯的行為---打印東北虎吃肉妮妮 加菲貓 1 雄---調用吃飯的行為---打印妮妮吃魚調用爬樹的行為---打印妮妮在樹上 class Animal:def __init__(self, brand, age, sex):self.__brand = brandself.__age = ageself.__sex = sexdef eat(self):print("吃飯") ''' 隱藏起來的內容只有在當前類中可以使用 出了當前類沒有任何意義 想對外提供 只能提供獲取或者設置的方法 '''def get_brand(self):return self.__brandclass Cat(Animal):def __init__(self, brand, age, sex, name):super().__init__(brand, age, sex)self.__name = namedef eat(self):print("%s在吃魚" % self.__name)def climb(self):print("%s在樹上" % self.__name)class Tiger(Animal):def __init__(self, brand, age, sex):super().__init__(brand, age, sex)def eat(self):print("%s在吃肉" % self.get_brand())from listen.cat_tiger import * def main():#創建一個老虎對象tiger = Tiger("東北虎", 2, "雌")tiger.eat()#創建一個貓的對象cat = Cat("加菲貓", 1, "雄", "妮妮")cat.eat()cat.climb()if __name__ == "__main__":main()2.今日課堂概述
1.繼承體系中__slots__的使用 2.多繼承與多層繼承中子類的繼承順序與如何調用多個父類中的構造方法 3.get/set方法屬性化 4.運算符系統方法重寫 5.類屬性和類方法 6.動態語言與靜態語言 7.深拷貝與淺拷貝 8.常用系統屬性__name____dict____bases__3.繼承體系中slots的使用
__slots__限制不讓對象隨意的動態添加屬性--->[限制只會限制當前類] 如果在繼承體系中:父類中做了限制 在子類中沒有設置slots的字段值 這種限制對應子類無效想讓子類也有限制作用 需要在子類中把slots這個字段聲明 是在父類的基礎上進行添加 class Animal:__slots__ = ("brand", "age")def __init__(self, brand, age):self.brand = brandself.age = ageclass Dog(Animal):__slots__ = ("name")def __init__(self, name, brand, age):self.name = namesuper().__init__(brand, age)self.sex = "雄" # 錯誤# 調用打印方法時 打印對象的引用變量def __str__(self):return "Dog name:%s brand:%s age:%d" % (self.name, self.brand, self.age)from slots_pack.animal import * def main():# 創建一個dog對象dog = Dog("旺財", "二哈", 2)print(dog)if __name__ == "__main__":main()4.多繼承與多層繼承中子類的繼承順序與如何調用多個父類中的構造方法
多繼承與多層繼承中子類的繼承順序 ---> 采用廣度繼承制度這種狀態的查看時機是子類沒有從父類中繼承任何屬性 但是確實是存在繼承關系 可以從類名.mro() ---> 查看當前類的繼承體系 類名.__bases__ ---> 查看的是直接父類 class Animal:def __init__(self):print("動物祖宗初始化方法")class Mammal(Animal):def __init__(self):print("哺乳類")super().__init__()class Runnable(Animal):def __init__(self):print("爬行類")super().__init__()class Dog(Mammal, Runnable):def __init__(self):print("底層子類")super().__init__()res = Dog.mro() print(res) ''' [<class '__main__.Dog'>, <class '__main__.Mammal'>, <class '__main__.Runnable'>, <class '__main__.Animal'>, <class 'object'>] 底層子類 哺乳類 爬行類 動物祖宗初始化方法 '''如何調用多個父類中的構造方法如果多個父類中有屬性需要子類繼承 子類該如何調用父類的__init__方法父類類名.__init__(self, 父類需要的屬性列表) class Father:def __init__(self,name,sex):print("父親")self.name = nameself.sex = sexclass Mother:def __init__(self, love):print("母親")self.love = loveclass Son(Father, Mother):def __init__(self, name, love, sex):# 父類類名.__init__(self, 父類參數列表)Father.__init__(self, name, sex)Mother.__init__(self, love)5.get/set方法屬性化
封裝之后 外界想獲取屬性值:
提供get方法 ---> 調用方法才可以獲取屬性值封裝之后 外界想設置屬性值:
提供set方法 ---> 調用方法在方法中傳遞數據屬性化 —> 將調用方法的格式 轉化為 類似于普通屬性的獲取方式
將get方法屬性化的方式在get方法上 添加裝飾器 @property調用方法時 可以只寫方法名 不用添加小括號 自動將方法進行調用值 = 對象.get方法名 注意:如果沒有添加@property裝飾器 就是一個普通的方法 調用的時候必須添加小括號將set方法屬性化的方式set屬性化的裝飾器 是在對應的get方法的基礎上衍生來的@get方法名.setter屬性化之后 調用就類似與普通屬性那樣使用等號來進行賦值對象.set方法名 = 值 注意:如果沒有添加@get方法名.setter裝飾器 就是一個普通的方法 調用的時候必須添加小括號 并在小括號中賦值class Person:__slots__ = ("name", "__age", "__sex")def __init__(self, name, age, sex):self.name = nameself.set_age = ageself.set_sex = sex@propertydef get_age(self):return self.__age@get_age.setterdef set_age(self, age):if age < 0:self.__age = 0else:self.__age = age@propertydef get_sex(self):return self.__sex@get_sex.setterdef set_sex(self, sex):if sex in ("男", "女"):self.__sex = sexelse:self.__sex = "男"def __str__(self):return "Person name:%s age:%d sex:%s" % (self.name, self.__age, self.__sex)__repr__ = __str__from set_get_property.person import Person def main():# 創建人的對象person = Person("楊陽", 18, "女")print(person)# 獲取這個對象的名字name = person.nameprint(name)# 將get方法進行屬性化 調用方法的時候 不使用小括號來調用 直接把方法名當做普通的屬性來進行使用 sex = person.get_sexprint(sex)# 獲取年齡age = person.get_ageprint(age)# 賦值# 給name進行重新賦值person.name = "羊羊羊"print(person)# 將set方法屬性化之后 調用的時候直接調用方法名即可 賦值的時候 用類似于普通屬性那種等號賦值方式賦值即可person.set_sex = "男"print(person)# 修改年齡person.set_age = 20print(person)if __name__ == "__main__":main()6.運算符系統方法重寫
字符串:+*>=<=><==!=%class Pointer:def __init__(self, pass_x, pass_y):self.x = pass_xself.y = pass_ydef __add__(self, other):# self + othernew_x = self.x + other.xnew_y = self.y + other.ynew_p = Pointer(new_x, new_y)return new_pdef __mul__(self, value):# self * valueself.x = self.x * valueself.y *= 5return selfdef __eq__(self, other):#self == otherif self.x == other.x and self.y == other.y:return Trueelse:return Falsedef __ne__(self, other):#self != otherif self.x != other.x or self.y != other.y:return Trueelse:return Falsedef __ge__(self, other):#self >= otherif self.x >= other.x or self.y >= other.y:return Trueelse:return Falsedef __le__(self, other):#self <= otherif self.x <= other.x or self.y <= other.y:return Trueelse:return Falsedef __gt__(self, other):# self > otherif self.x > other.x or self.y > other.y:return Trueelse:return Falsedef __lt__(self, other):#self < otherif self.x < other.x or self.y < other.y:return Trueelse:return Falsedef __mod__(self, value):#self % valueself.x %= valueself.y %= valuereturn selfdef __str__(self):return "Pointer x:%d y:%d" % (self.x, self.y)__repr__ = __str__p1 = Pointer(1, 2) print(id(p1)) print(p1) p2 = Pointer(1, 2) print(id(p2)) # 將兩個點的坐標相加 生成一個新的點的對象 res = p1 + p2 print(res) print(id(res))# 乘法 可以乘以一個數值n 將原有的對象的坐標點的值 坐標值是原有基礎上數值n的倍數 res =p1 * 5 print(id(res)) print(res)# 如果不重寫 對應的方法 默認比較是地址 print(p1 == p2) print(p1 == res)# 進行重寫 比較坐標點 一樣返回True p3 = Pointer(2, 4) p4 = Pointer(2, 4) print(p3 == p4)使用比較多的
__eq__(self, other): 如果不重寫 默認比較的是地址 重寫的話一般是判定偽相等 只要兩個對象滿足某些需求 就判定兩個對象相等 例如: 在程序中有一個人類屬性: 身份證號現在有兩個人類對象 以現實生活需求判定 這兩個對象是否是同一個人只要兩個對象的身份證號一致 視為同一個人 class Person:def __init__(self, cardid, name):self.name = nameself.cardid = cardiddef __eq__(self, other):#self == otherif self.cardid == other.cardid:return Trueelse:return Falsep1 = Person(100001, "張三") p2 = Person(100001, "李四") p3 = Person(100002, "張三") print(p1 == p2) # True print(p1 == p3) # False7.類屬性和類方法:
對象屬性在創建對象的時候 self后面的變量名就是對象屬性被包含在__init__方法中的 類屬性直接被包含在類體中 與其他方法是平級的什么時候使用類屬性?當該類所有對象的某個屬性的值一致時 就可以將其提為類屬性 類屬性是被該類所有對象所共享的 類屬性是屬于類的 被加載到方法去中 只要是該類對象 就具有了該屬性使用的時候 可以使用對象進行調用 也可以使用類進行調用 建議使用類進行調用案例:
人類:name agesexcountry[國籍] ---> 所有人的國籍都是CH class Person:__slots__ = ("name", "age", "sex")__country = "CH"def __init__(self, name, age, sex):self.name = nameself.age = ageself.sex = sex@classmethoddef get_country(cls):print(cls)return cls.__countrydef __str__(self):return "Person name:%s age:%d sex:%s country:%s" % (self.name, self.age, self.sex, self.__country)__repr__ = __str__from class_property_method.person import Person def main():p1 = Person("張三", 20, "男")p2 = Person("李四", 21, "男")p3 = Person("王五", 22, "女")print(p1)print(p2)print(p3)print(Person.get_country())print(p1.get_country())if __name__ == "__main__":main() ''' Person name:張三 age:20 sex:男 country:CH Person name:李四 age:21 sex:男 country:CH Person name:王五 age:22 sex:女 country:CH <class 'class_property_method.person.Person'> CH <class 'class_property_method.person.Person'> CH '''對象方法:特點: 方法的第一個形參為self ---> 表示的是調用方法的對象調用該方法通過對象來調用 類方法:需要裝飾器 @classmethod 將方法裝飾成類方法類方法的第一個形參: cls ---> 表示的是當前類這個參數與self類似 不需要手動傳值 通過類或者對象調用時 會自動將其類型賦值給cls什么時候使用類方法?類方法一般是操作類屬性的類屬性和類方法建議使用類來進行調用 靜態方法[了解]需要使用裝飾器 @staticmethod 將方法裝飾成靜態方法靜態方法中的形參個數是根據需求來確定的 沒有多余的類似于對象方法的self 和 類方法的cls 一般來使用的話 也是通過類名來進行調用該練習:
學生類:nameagesexcount ---> 學生個數 要求:創建n個學生對象 統計學生個數不管用哪個學生對象調用個數 個數都是一致的 例如:s1 = s2 = s3 = print(s1.count) # 3 如何檢測對象被創建了 ---> init class Student:__stu_count = 0def __init__(self, name, age, sex):self.name = nameself.age = ageself.sex = sex# 這個方法可以檢測對象是否創建Student.__stu_count += 1@classmethoddef get_count(cls):#print(self.name)return cls.__stu_count@staticmethoddef show_info(info):print("這是一個靜態方法")if __name__ == "__main__":s1 = Student("小明", 17, "男")s2 = Student("小剛", 16, "男")s3 = Student("小強", 18, "男")print(s1.get_count()) # 3print(s2.get_count()) # 3print(s3.get_count()) # 3Student.show_info("內容") # 這是一個靜態方法res = Student.get_count() # 3print(res)注意:
在類方法中不允許出現self 原因:類方法加載的時候還沒有對象 就不能使用與對象相關的內容 從創建對象的過程:p = Person("小明", 12, "男") 內存中的變化:1. 將Person類加載到方法區內存中跟隨者一起加載到內存中的有 類屬性和類方法2.在對中開辟一塊內存 存放該類聲明的對象 并產生一個地址跟隨者加載的有對象屬性3. 將創建對象是傳遞的數據 給對象屬性進行初始化4. 將對象的地址 賦予給變量p8.靜態語言和動態語言
靜態語言:
聲明變量時 必須先聲明出該變量的類型 給變量賦值的時候 只能賦予該類型的數據java動態語言:
變量的類型是根據賦值來決定的Python屬于動態語言 --- 本身就是多態的變量賦予什么類型的數據 展現就是對應的類型class Pet:def __init__(self, name, age, sex, power):self.name = nameself.age = ageself.sex = sexself.power = powerclass PetDog(Pet):def __init__(self, name, age, sex, power):super().__init__(name,age,sex,power)def look_home(self):print(self.name, "在看家")class PetCat(Pet):def __init__(self, name, age, sex, power):super().__init__(name, age, sex, power)def catch_mouse(self):print(self.name, "抓老鼠")class Host:def __init__(self, name):self.name = name# 根據不同的場景 隨時切換不同的類型 這個就是多態def introduce(self, pet):# 如何判斷變量接受的是什么類型if isinstance(pet, PetDog):print("我家狗叫%s, %d歲了, 會%s" % (pet.name, pet.age, pet.power))elif isinstance(pet, PetCat):print("我家貓叫%s, %d歲了, 會%s" % (pet.name, pet.age, pet.power))from polymorphic.pet import * def main():dog = PetDog("旺財", 2, "雌", "兩條腿走路")cat = PetCat("加菲", 2, "雄", "裝死")host = Host("baby")host.introduce(dog)host.introduce(cat)if __name__ == "__main__":main()9.常用字段
常用系統屬性
__name__--- 類來調用 結果類的字符串名字 __dict__--- 一般常用與使用對象來調用返回的是一個字典 字典中包含的數據 { 對象屬性:屬性值, 對象屬性:屬性值} __bases__--- 元組 包含繼承的父類 class Person:def __init__(self, name, age):self.name = nameself.age = ageif __name__ == "__main__":res = Person.__name__print(type(res)) # <class 'str'>print(res) # Personp = Person("小剛", 20)res = p.__dict__print(res) # {'name': '小剛', 'age': 20}res = Person.__bases__print(res) # (<class 'object'>,)10.深拷貝和淺拷貝
對于不可變對象 是沒有拷貝這個功能的
淺拷貝:
只會拷貝最外層對象 內層對象還是引用的原來的地址深拷貝:
內外都會生成一個新的對象 占用的地址不一樣需要借助模塊 copy
import copy # 不可變對象是沒有拷貝行為的 不管如何進行操作 獲取的都是原來地 地址 沒有生成新的對象 str0 = "abc" print(id(str0)) # 2445453913424 # 對其進行淺拷貝 res = copy.copy(str0) print(id(res)) # 2445453913424 # 對其進行深拷貝 res = copy.deepcopy(str0) print(id(res)) # 2445453913424class Person:def __init__(self, name):self.name = namedef __str__(self):return "Person name:%s" % self.name__repr__ = __str__# 可變對象的拷貝行為 person = Person("小黃") print("人類對象的地址:",id(person)) # 人類對象的地址: 2445454886728list0 = ["abc", True, 10, person] print("原列表中引用的人類對象的地址",id(list0[3])) # 2445454886728 print("原列表地址:", id(list0)) # 2445456412488# 淺拷貝 將最外層對象拷貝出來一個新的對象 但是內部的其他對象引用還是原來的地址 new_list = copy.copy(list0) print(new_list) print("淺拷貝出來的新列表的地址:", id(new_list)) # 2445456411080 print("淺拷貝出來的新列表引用的人類對象的地址:", id(new_list[3])) # 2445454886728# 深拷貝: 內外對象都會拷貝出來一個新的對象 deep_list = copy.deepcopy(list0) print(deep_list) print("深拷貝出來的新列表的地址:", id(deep_list)) # 2445456412496 print("深拷貝出來的新列表引用的人類對象的地址:", id(deep_list[3])) # 2445454886896 ''' 列表的方法中 提供了淺拷貝的方法 凡是可變對象的 都提供了一個淺拷貝的方法 '''總結
以上是生活随笔為你收集整理的Python基础_Day13的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言,最新猴子摘桃(递归方法)
- 下一篇: 无形营销