摘要:構(gòu)造函數(shù)構(gòu)造函數(shù)參數(shù)列表在使用類創(chuàng)建對象時自動調(diào)用。類是從一堆對象中抽取相同的屬性及方法得出的,抽象類就是從一堆類中抽取相同的屬性及方法得出的。抽象類不能實例化對象。
1.構(gòu)造函數(shù)
構(gòu)造函數(shù):__init__(參數(shù)列表) :在使用類創(chuàng)建對象時自動調(diào)用。
注意:如果自己不寫構(gòu)造函數(shù),系統(tǒng)默認(rèn)也會加上一個空的構(gòu)造函數(shù)。
對象屬性的優(yōu)先級高于類屬性,當(dāng)對象調(diào)用屬性時,如果有對象屬性時,先獲取對象屬性的值;如果沒有對象屬性,會去找同樣名字的類屬性;如果沒有同樣名字的類屬性,返回一個錯誤。
class Person(): # 直接寫在class中的屬性叫類屬性(可以通過類名直接調(diào)用) # name = "" # age = 0 # 默認(rèn)的構(gòu)造函數(shù)(在init方法中的屬性叫對象屬性) # __init__函數(shù)沒有返回值,不能寫return # def __init__(self): # pass # 自己重新寫構(gòu)造函數(shù)時,只能更改參數(shù)列表及函數(shù)體,不能寫return這條語句 # def __init__(self): # print("我顯示的是init函數(shù)") def __init__(self, name, age, weight=30.0): print("小兔子乖乖") # 對象屬性(定義在構(gòu)造函數(shù)中的屬性為對象屬性) self.name = name self.age = age self.weight = weight # 建議:一個類中最好只有一個init函數(shù),如果寫了多個,程序不會報錯, # 但是只會執(zhí)行最后一個寫的init函數(shù) def eat(self): print("person--eat") def sleep(self, hours): print("我睡了%d小時" % hours) # 建議使用關(guān)鍵字 實例化對象 per1 = Person(name="Lily", age=30, weight=50.0)2.self和__class__
self:當(dāng)前類的實例對象,但是在類中用self表示。3.析構(gòu)函數(shù)
哪個對象調(diào)用帶有self參數(shù)的方法時,self就指向哪一個對象。__class__: 代表當(dāng)前類的類名。
self:不是關(guān)鍵字,換成其他的詞語也可以,只要類中的成員方法至少有一個形參即可,第一個形參就代表當(dāng)前類的實例對象
析構(gòu)函數(shù):__del__() : 釋放對象時調(diào)用,銷毀對象時調(diào)用。
class Person(): # 構(gòu)造函數(shù) def __init__(self, name): self.name = name def __del__(self): print("析構(gòu)函數(shù)" + self.name) per1 = Person("tom") per2 = Person("lucy") per3 = Person("lily") # del per3.name 刪除對象屬性 # del per3 # 手動刪除優(yōu)先級高 先刪除lily 然后執(zhí)行類里的析構(gòu)函數(shù),系統(tǒng)的自動回收 def fun1(): per4 = Person("Json") # 局部變量 print(per4.name) fun1() # Json 析構(gòu)函數(shù)Json 用完函數(shù)后 per4 被析構(gòu)函數(shù)回收4.__str__函數(shù)
在使用print打印對象時會自動調(diào)用,這個方法是給用戶使用的,是描述對象的方法。
class Person(): def __init__(self, name, age, sex): self.name = name self.sex = sex self.age = age # 可以在類中重新寫__str__方法 # 要求必須有返回值,返回值類型str類型 def __str__(self): sexStr = "" if self.sex == 1: sexStr = "女" elif self.sex == 0: sexStr = "男" return "姓名為%s, 年齡為%d,性別為%s" %(self.name, self.age, sexStr)5.訪問限制
私有屬性子類不能繼承,子類的對象不能使用
實例對象不能直接訪問私有屬性__age,因為python解釋器把__age私有屬性變成了_Person__age, 我們就可以通過_Person__age訪問私有屬性__age。強(qiáng)烈建議:不要這么干
class Person(): def __init__(self, name, age, weight, height): # 公有屬性:能夠在當(dāng)前類、當(dāng)前類的實例對象、子類中均能使用 self.name = name # 私有屬性: 只能在當(dāng)前類中使用 # 格式:__屬性名(只在屬性名前面加兩個下劃線) self.__age = age # 格式:__變量名__:在python中屬于特殊變量,可以直接訪問,類似公有屬性 self.__weight__ = weight # 格式: _變量名:在python中能夠正常訪問,類似公有屬性,但是,當(dāng)我們 # 看到這種屬性時,把它當(dāng)成是私有屬性使用。 # _變量名(雖然我現(xiàn)在能直接訪問并使用,但請把我當(dāng)成私有屬性,不要用 # 對象直接訪問) self._height = height # set方法:賦值 def setAge(self, age): if age < 0: self.__age = 20 else: self.__age = age # get方法: 取值 def getAge(self): return self.__age + 20 def setName(self, name): self.name = name def getName(self): return self.name6.繼承
class Animal(): def __init__(self, name, color, age): self.name = name self.age = age # 私有屬性 self.__color = color def run(self): print(self.__color) print("run") def eat(self): print("eat") class Cat(Animal): def __init__(self, name, age, color, miao): # 調(diào)用父類的__init__方法 # 父類名稱.__init__(self, 根據(jù)父類形參賦值實參) Animal.__init__(self, name, color, age) # 使用super關(guān)鍵字調(diào)用init方法(同上) # super(Cat, self).__init__(name, color, age) # 子類可以有自己獨有的屬性 self.miao = miao7.多重繼承和多繼承
單繼承:一個子類只有一個父類8.類方法及靜態(tài)方法
多重繼承:子類有父類,父類又有父類 : 父類->子類->子子類。。。。。
多繼承: Son -> Father,Mother
注意:如果父類們中的方法名相同,默認(rèn)調(diào)用小括號中排在前面的父類中的方法(就近原則)
類方法 @classmethod
類方法一般來說使用類名調(diào)用。
類方法類和對象均能調(diào)用,但是不管是類還是對象調(diào)用,cls都代表類;比如當(dāng)前例子中,cls就代表Person,cls不是關(guān)鍵字,使用其他形參名稱也可以,總之,類方法的第一個形參就代表類。靜態(tài)方法 @staticmethod
靜態(tài)方法一般來說不是給對象是用的,一般使用類名調(diào)用
靜態(tài)方法就是一個普通函數(shù),不會默認(rèn)需要傳參數(shù)
類和對象均能調(diào)用,但一般使用類名調(diào)用
class Person(): # 對象方法,使用實例對象調(diào)用 def eat(self): print("eat") # 類方法 @classmethod @classmethod def play(cls, a, b): print("類方法", a+b) print(cls) # 靜態(tài)方法 @staticmethod @staticmethod def run(num1, num2): print(num1 + num2)9.動態(tài)添加屬性及方法及__slots__屬性
from types import MethodType class Person(): def run(self): print("run") pass # 動態(tài)添加屬性 per1 = Person() per1.name = "Lily" print(per1.name) # 動態(tài)添加方法 def say(self): print("say") # MethodType(函數(shù)名稱, 當(dāng)前實例對象的名稱) # 把當(dāng)前的實例對象傳遞給函數(shù)的第一個形參 per1.saying = MethodType(say, per1) per1.saying()
思考:如果我們要限制動態(tài)添加屬性或方法的個數(shù)及名稱怎么辦?比如我們只能動態(tài)添加name及age屬性,run方法。為了達(dá)到要求,python允許在定義類時,定義一個特殊的屬性__slots__屬性變量,__slots__屬性可以限制動態(tài)添加的屬性及方法的名稱。
__slots__ :使用元組的方式賦值
注:__slots__定義的屬性只對當(dāng)前類有效,對它繼承的子類無效;
如果子類中也定義了__slots__屬性,這樣定義的屬性的個數(shù)為子類本身的內(nèi)容加上父類中定義的內(nèi)容。
class Student(): __slots__ = ("name", "age", "run") pass stu1 = Student() stu1.name = "Tom" # stu1.weight = 56.7 # 錯誤,不允許添加 def run(self, a, b): print("run", a+b) stu1.run = MethodType(run, stu1) stu1.run(2,3)10.@property
@property 裝飾器
@property: 可以使對象通過點方法訪問私有屬性。
class Person(): def __init__(self, name, age): # 公有屬性 self.name = name # 私有屬性 self.__age = age @property def age(self): return self.__age @age.setter def age(self, age): if age < 0: age = 1 self.__age = age per1 = Person(name="二胖", age=1) # 如果屬性為公有屬性,對象可以直接調(diào)用進(jìn)行更改或使用 # 這樣,不安全,數(shù)據(jù)可以直接被重新賦值,而且沒有任何限制條件。 # 相當(dāng)于調(diào)用set方法,現(xiàn)在調(diào)用的是加了@age.setter裝飾器的方法 per1.age = 99 # 相當(dāng)于調(diào)用get方法,現(xiàn)在調(diào)用的是加了@property裝飾器的方法 print(per1.age)11.運算符重載
class Person(): def __init__(self, num): self.num = num # 打印對象時調(diào)用 def __str__(self): return "目前num為:" + str(self.num) # 運算符重載 def __add__(self, other): return Person(self.num + other.num) def __mul__(self, other): return Person(self.num * other.num) p1 = Person(100) print(p1) p2 = Person(266) print(p2) print(p1 + p2) # p1.__add__(p2) __add__(self, other) Person(111) Person(111) print(p1 * p2) __init__: 構(gòu)造函數(shù) __del__:析構(gòu)函數(shù) __str__:打印對象 __add__:加運算 __mul__:乘運算 __sub__:減運算 __mod__:余運算 __div__:除運算 __pow__:冪運算12.抽象類
在開發(fā)中,我們遇到的所有事物都是對象,對象是通過類創(chuàng)建的。但是不是所有的類都是用來描述對象的。如果一個類中沒有足夠的條件信息來描述一個具體的事物/對象,而需要其他具體的類來輔助他,那么,這樣的類我們稱之為抽象類。抽象類中可以有抽象方法,一般包含抽象方法的類都是抽象類。
抽象方法可以不包含任何方法實現(xiàn)的代碼,只有一個方法名字,但是,在子類中要求必須實現(xiàn)該抽象方法,否則,子類也為抽象類。類是從一堆對象中抽取相同的屬性及方法得出的,抽象類就是從一堆類中抽取相同的屬性及方法得出的。
抽象類不能實例化對象。
1、定義抽象類
在定義抽象類之前,我們需要導(dǎo)入模塊abc中的ABCMeta類(抽象基類的元類)(Metaclass for defining Abstract BaseClass)。在定義抽象類時,我們需要在代碼中加入 metaclass=ABCMeta,指定該類的元類為ABCMeta元類:創(chuàng)建一個類的類。
抽象類不能實例化對象。
抽象類一般都用作父類。2、定義抽象方法
在定義抽象方法之前,我們需要導(dǎo)入模塊abc中的abstractmethod類。
在定義抽象方法時,我們需要在方法前面加上@abstractmethod修飾詞。
因為抽象方法一般不需要在抽象類中實現(xiàn),我們只需要在抽象方法的函數(shù)體中寫一條pass語句即可。3、實現(xiàn)類
實現(xiàn)類為抽象類的子類。
如果實現(xiàn)類不實現(xiàn)父類(抽象類)中的抽象方法,那么該類也是抽象類;
如果實現(xiàn)類實現(xiàn)了父類(抽象類)中的抽象方法,那么該類就是普通類,可以實例化對象。
from abc import ABCMeta, abstractmethod # 定義抽象類 class Animal(metaclass=ABCMeta): # 定義屬性 def __init__(self, color): self.color = color # 對象方法 def eat(self): print("Animal--eat") # 定義抽象方法 @abstractmethod def play(self): pass # 創(chuàng)建實現(xiàn)類(以一個抽象類為父類) class Cat(Animal): def __init__(self, color, name): Animal.__init__(self, color) self.name = name # 子類實現(xiàn)父類的抽象方法 def play(self): print("cat--play") cat1 = Cat(color="black", name="旺財") print(cat1.color)13.接口
真正的接口中不能定義變量,接口中只能有抽象方法。1.什么是接口 interface,接口都是當(dāng)作父類使用。
子類實現(xiàn)接口中的抽象方法。
在python中沒有interface這個關(guān)鍵字,我們目前所寫的接口只是通過抽象類仿寫,
所以,目前,接口可以認(rèn)為就是一個類,一個只包含抽象方法并且不能實例化對象的類。其子類如果想要實例化對象,必須實現(xiàn)接口中所有的抽象方法。2.為什么要使用接口?
接口本身就是一系列方法的聲明,一些特殊方法的集合,一個接口中只有方法的聲明,但是沒有方法的實現(xiàn),這些特殊的方法要在不同的類之間進(jìn)行不同的實現(xiàn)。接口本身是用于封裝代碼的。例子:鳥類和昆蟲類都有飛行的行為,功能相同,但實現(xiàn)內(nèi)容不同,二者如果抽象出一個類不太方便,但可以抽象一個接口,用于飛行行為的封裝。
3.注意:一般在接口中只有方法的聲明,沒有方法的實現(xiàn)。在接口中不能出現(xiàn)變量。
from abc import abstractmethod # 定義接口 class Interface: # 仿寫接口 # 定義抽象方法 @abstractmethod def fly(self): pass # ... # 定義接口的實現(xiàn)類 class Bird(Interface): def __init__(self, leg): self.leg = leg def egg(self): print("鳥生蛋") def fly(self): print("小鳥飛的高") class Insect(Interface): def __init__(self, leg): self.leg = leg def spawn(self): print("昆蟲產(chǎn)卵") def fly(self): print("昆蟲飛的低") b1 = Bird(2) b1.fly() i1 = Insect(6) i1.fly()14.多態(tài)
面向?qū)ο蟮娜筇卣鳎?封裝,繼承,多態(tài)
多態(tài):一種事物的多種形態(tài),子類可以認(rèn)為是父類的不同形態(tài)的實現(xiàn)python是弱類型語言,聲明變量時,不要求數(shù)據(jù)類型,根據(jù)賦值的類型去確定該變量的類型。c,Java強(qiáng)類型語言,聲明變量時,已經(jīng)確定該變量的數(shù)據(jù)類型,如果賦值的類型與聲明的類型不一致,程序會報錯。在強(qiáng)類型語言中:子類對象可以強(qiáng)轉(zhuǎn)為父類類型的對象,但父類類型的對象不能強(qiáng)轉(zhuǎn)為子類類型的對象。在強(qiáng)類型語言中:子類對象可以強(qiáng)轉(zhuǎn)為父類類型的對象,父類類型的對象也能強(qiáng)轉(zhuǎn)為子類類型的對象。
class Animal(): def __init__(self, name): self.name = name def eat(self): print(self.name + "eat") class Cat(Animal): def __init__(self, name): Animal.__init__(self, name) def run(self): print(self.name + "run") class Dog(Animal): def __init__(self, name): Animal.__init__(self, name) class Person(): # def feedAnimalCat(self, cat): # print("人喂了" + cat.name) # def feedAnimalDog(self, dog): # print("人喂了" + dog.name) def feedAnimal(self, animal): print("人喂了" + animal.name) per = Person() cat1 = Cat("喵") # per.feedAnimalCat(cat1) dog1 = Dog("汪") # per.feedAnimalDog(dog1) per.feedAnimal(cat1) per.feedAnimal(dog1)
class Animal(object): def run(self): print("animal is running") class Dog(object): def run(self): print("dog is running") class Cat(object): def run(self): print("cat is running") def run_twice(animal): animal.run() animal.run() run_twice(Animal()) run_twice(Cat()) run_twice(Dog()) class Tortoise(Animal): def run(self): print("Tortoise is running slowly...") run_twice(Tortoise())
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/41602.html
摘要:看起來好像是廢話,它還有一個補充的說明,在函數(shù)式編程中要避免狀態(tài)變化和使用可變對象。函數(shù)式編程的特點在中,函數(shù)即對象,例如聲明一個函數(shù)之后,你可以調(diào)用其屬性。 ...
摘要:一面向?qū)ο缶幊?。是一門面向?qū)ο蟮木幊陶Z言,通過對象實現(xiàn)對方法的調(diào)用。面向過程的程序設(shè)計把計算機(jī)程序視為一系列的命令集合,即一組函數(shù)的順序執(zhí)行。對于面向?qū)ο笳Z言,重要的概念是類和實例。 一、preface 面向?qū)ο缶幊蘋OP:object oriented programming。OOP把對象作為程序的基本單元,一個對象包含了數(shù)據(jù)和操作數(shù)據(jù)的函數(shù)。Python是一門面向?qū)ο蟮木幊陶Z言,...
摘要:語料庫是由文本構(gòu)成的數(shù)據(jù)集通過提供現(xiàn)成的文本數(shù)據(jù)來輔助文本處理。那么可以用來做什么呢我自己是一名從事是不錯的入門選項。大數(shù)據(jù)和人工智能是機(jī)器學(xué)習(xí)和的主要開發(fā)語言。 Python培訓(xùn)有哪些內(nèi)容?很多零基礎(chǔ)學(xué)員不知道Python軟件是干什么用的?Python軟件是Python工程師編寫代碼時所需...
摘要:如果初學(xué)者接觸的第一門語言是,學(xué)習(xí)曲線則會平滑得多,掌握一些基本語法和內(nèi)置的數(shù)據(jù)結(jié)構(gòu),已經(jīng)可以上手寫一些小工具或者小型應(yīng)用。如果你的學(xué)習(xí)時間充足,我的建議是一定要學(xué)數(shù)據(jù)結(jié)構(gòu)和算法。 前言 Python是最容易入門的編程語言,沒有之一。如果初學(xué)者接觸的第一門語言是C或者C++,對他們來說最難的不是語法,而是容易出現(xiàn)內(nèi)存泄漏、指針等問題。有時候排查這些問題對初學(xué)者的打擊很大,尤其是沒掌握排...
摘要:反對者在某些領(lǐng)域?qū)Υ擞枰苑裾J(rèn)。下面再引用一段來自維基百科中關(guān)于的歷史。類的更嚴(yán)格的定義是由某種特定的元數(shù)據(jù)所組成的內(nèi)聚的包。類還可以有運行時表示形式元對象,它為操作與類相關(guān)的元數(shù)據(jù)提供了運行時支持。 在開始部分,請看官非常非常耐心地閱讀下面幾個枯燥的術(shù)語解釋,本來這不符合本教程的風(fēng)格,但是,請看官諒解,因為列位將來一定要閱讀枯燥的東西的。這些枯燥的屬于解釋,均來自維基百科。 1、問題...
閱讀 3207·2021-11-25 09:43
閱讀 3417·2021-11-11 16:54
閱讀 843·2021-11-02 14:42
閱讀 3769·2021-09-30 09:58
閱讀 3675·2021-09-29 09:44
閱讀 1287·2019-08-30 15:56
閱讀 2109·2019-08-30 15:54
閱讀 2995·2019-08-30 15:43