溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Python中面向?qū)ο蟮奶卣饔心男?/h1>
發(fā)布時間:2022-02-14 09:32:27 來源:億速云 閱讀:92 作者:小新 欄目:開發(fā)技術(shù)

這篇文章給大家分享的是有關(guān)Python中面向?qū)ο蟮奶卣饔心男┑膬?nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

面向?qū)ο笕筇卣鹘榻B

封裝(隱藏):隱藏對象的屬性和實現(xiàn)細節(jié),知對外提供必要的方法。

繼承:讓子類擁有父類特征,提高了代碼的重用性。從設(shè)計上是一種增量進化,原有父類設(shè)計不變的情況下,可以增加新的功能,或者改進 已有的算法。

多態(tài):一個方法調(diào)用由于對象不同會產(chǎn)生不同的行為。

繼承

繼承是代碼復(fù)用的一個非常重要的手段,已有的類,我們稱為“父類或者基類”,新的類,我們稱為“子類或者派生類”。

Python中面向?qū)ο蟮奶卣饔心男?></p><h4>語法格式</h4><p>Python 支持多重繼承,一個子類可以繼承多個父類。繼承的語法格式如下:</p><blockquote><p>class 子類類名(父類 1[,父類 2,&hellip;]):<br/>&emsp;類體</p></blockquote><p>如果在類定義中沒有指定父類,則默認父類是 object 類。也就是說,object 是所有類的父 類,里面定義了一些所有類共有的默認實現(xiàn),比如:<strong>new</strong>()。</p><p><strong>定義子類時</strong>,<strong>必須在其構(gòu)造函數(shù)中調(diào)用父類的構(gòu)造函數(shù)</strong>。調(diào)用格式如下:</p><blockquote><p>父類名.<strong>init</strong>(self, 參數(shù)列表)</p></blockquote><pre class=# 測試繼承的基本使用 class Person():     def __init__(self, name, age):         self.name = name         self.__age = age #私有屬性     def print_name(self):         print(self.name) class Student(Person):     def __init__(self, name, age, id):         Person.__init__(self, name, age)         self.id = id stu = Student('sherry',24,'2017') stu.print_name() print(Student.mro()) #查看類的繼承層次結(jié)構(gòu) print(dir(stu))  # 打印所有方法和屬性 print(stu._Person__age) #繼承于父類的私有屬性的訪問 輸出: sherry [<class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>] ['_Person__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'id', 'name', 'print_name'] 24

1.類成員的繼承和重寫 成員繼承:子類繼承了父類除構(gòu)造方法之外的所有成員,包括方法,屬性,私有方法,私有屬性,只不過私有方法和屬性不能直接訪問。

2.方法重寫:子類可以重新定義父類中的方法,這樣就會覆蓋父類的方法,也稱為“重寫”

# 重寫父類方法的測試
class Person():
    def __init__(self, name, age):
        self.name = name
        self.__age = age #私有屬性
    def print_name(self):
        print(self.name)
class Student(Person):
    def __init__(self, name, age, id):
        Person.__init__(self, name, age)
        self.id = id
    def print_name(self):
        '''重寫了父類的方法'''
        print('my name is ', self.name)
stu = Student('sherry',24,'2017')
stu.print_name()
輸出:
my name is  sherry

查看類的繼承層次結(jié)構(gòu)

通過類的方法 mro()或者類的屬性__mro__可以輸出這個類的繼承層次結(jié)構(gòu)。

class Person():
    def __init__(self, name, age):
        self.name = name
        self.__age = age #私有屬性
    def print_name(self):
        print(self.name)
class Student(Person):
    def __init__(self, name, age, id):
        Person.__init__(self, name, age)
        self.id = id
    def print_name(self):
        '''重寫了父類的方法'''
        print('my name is ', self.name)
# stu = Student('sherry',24,'2017')
print(Student.mro())
輸出:
[<class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>]

object根類

object 類是所有類的父類,因此所有的類都有 object 類的屬性和方法。

dir()查看對象屬性

# 測試繼承的基本使用
class Person():
    def __init__(self, name, age):
        self.name = name
        self.__age = age #私有屬性
    def print_name(self):
        print(self.name)
class Student(Person):
    def __init__(self, name, age, id):
        Person.__init__(self, name, age)
        self.id = id
    def print_name(self):
        '''重寫了父類的方法'''
        print('my name is ', self.name)
obj = object()
stu = Student('sherry',24,'2017')
print(dir(obj))
print(dir(stu))
輸出:
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
['_Person__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'id', 'name', 'print_name']

str()方法的重寫

object 有一個__str__()方法,用于返回一個對于“對象的描述”,對應(yīng)于內(nèi)置函數(shù) str()。經(jīng)常用于 print()方法,幫助我們查看對象的信息str()可以重寫。

class Person():
    def __init__(self, name, age):
        self.name = name
        self.__age = age #私有屬性
    def print_name(self):
        print(self.name)
    def __str__(self):
        return 'name:{0} age:{1}'.format(self.name, self.__age)
p = Person('sherry', 24)
print(p)
輸出:
name:sherry age:24

多重繼承

Python 支持多重繼承,一個子類可以有多個“直接父類”。這樣,就具備了“多個父 類”的特點。但是由于,這樣會被“類的整體層次”搞的異常復(fù)雜,盡量避免使用。(java不支持多重繼承)

Python中面向?qū)ο蟮奶卣饔心男?></p><pre class=class A():     pass class B():     pass class C(A,B):     pass print(C.mro()) 輸出: [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]

MRO()

Python 支持多繼承,如果父類中有相同名字的方法,在子類沒有指定父類名時,解釋器將 “從左向右”按順序搜索。

class A():
    pass
class B():
    pass
class C(A,B):
    pass
print(C.mro())
輸出:
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]

super()獲得父類定義

在子類中,如果想要獲得父類的方法時,我們可以通過 super()來做。super()獲得父類的定義(不是獲得父類的對象)。

# 測試super()
class A():
    def say(self):
        print('aa')
class B(A):
    def say(self):
        super().say()  #調(diào)用父類方法
        A.say(self)		#調(diào)用父類方法
        print('bb')
b = B()
b.say()
輸出:
aa
aa
bb

多態(tài)

多態(tài)(polymorphism)是指同一個方法調(diào)用由于對象不同可能會產(chǎn)生不同的行為。

關(guān)于多態(tài)要注意以下 2 點:

1.多態(tài)是方法的多態(tài),屬性沒有多態(tài)。

2.多態(tài)的存在有 2 個必要條件:繼承、方法重寫。

# 多態(tài)
class Man():
    def eat(self):
        print('eat!')
class Chinese(Man):
    def eat(self):
        print('eat with chopsticks')
class English(Man):
    def eat(self):
        print('eat with fork')
class Indian(Man):
    def eat(self):
        print('eat with hand')
def manEat(m):
    if isinstance(m,Man):
        m.eat()
    else:
        print('can not eat!') 
manEat(Man())
manEat(Chinese())
manEat(English())
manEat(Indian())     
輸出:
eat!
eat with chopsticks
eat with fork
eat with hand

特殊方法和重載運算符

python重的運算符實際上是通過調(diào)用對象的特殊方法實現(xiàn)的。

a = 20
b = 30
print(a+b)
print(a.__add__(b))
輸出:
50
50

常見的特殊方法:

Python中面向?qū)ο蟮奶卣饔心男?></p><p>每個運算符實際上都對應(yīng)了相應(yīng)的方法:</p><p><img src=# 測試運算符重載 class Person():     def __init__(self, name):         self.name = name     def __add__(self, other):         if isinstance(other, Person):             return '{0}-{1}'.format(self.name, other.name)     def __mul__(self, other):         if isinstance(other, int):             return self.name * other p1 = Person('Sherry') p2 = Person('Lily') print(p1 + p2) print(p1*10) 輸出: Sherry-Lily SherrySherrySherrySherrySherrySherrySherrySherrySherrySherry

特殊屬性

python中包含了很多雙下劃線開始和結(jié)束的屬性,這些是特殊屬性,有特殊用法。這里列出常見的特殊屬性:

Python中面向?qū)ο蟮奶卣饔心男?></p><pre class=#測試特殊屬性 class A():     def say(self):         print('aa') class B():     def say(self):         print('bb') class C(B,A):     def __init__(self,name):         super().__init__()         self.name = name c = C('sherry')  print(c.__dict__) #c對象的屬性列表 print(c.__class__) #c對象的類 print(C.__bases__) #C類的基類 print(C.__mro__) #C類的繼承關(guān)系 print(C.__subclasses__)#C類的子類 輸出: {'name': 'sherry'} <class '__main__.C'> (<class '__main__.B'>, <class '__main__.A'>) (<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>) <built-in method __subclasses__ of type object at 0x7fefdacc8dd0>

對象的淺拷貝和深拷貝

  • 變量的賦值操作

只是形成兩個變量,實際還是指向同一個對象。

  • 淺拷貝Python

拷貝一般都是淺拷貝??截悤r,對象包含的子對象內(nèi)容不拷貝。因此,源對象 和拷貝對象會引用同一個子對象。

  • &middot;深拷貝使用

使用copy 模塊的 deepcopy 函數(shù),遞歸拷貝對象中包含的子對象。源對象和拷貝對象 所有的子對象也不同。

# 測試淺拷貝和深拷貝
import copy
class MobilePhone():
    def __init__(self, cpu, screen):
        self.cpu = cpu
        self.screen = screen
class CPU():
    def caculate(self):
        print('cpu:\t', self)
class Screen():
    def show(self):
        print('screen:\t',self)
m1 = MobilePhone(CPU(), Screen())
print('測試賦值----')
m0 = m1
print('m1:\t',m1)
m1.cpu.caculate()
m1.screen.show()
print('m0:\t',m0)
m0.cpu.caculate()
m0.screen.show()
print('測試淺復(fù)制----')
m2 = copy.copy(m1)
print('m1:\t',m1)
m1.cpu.caculate()
m1.screen.show()
print('m2:\t',m2)
m2.cpu.caculate()
m2.screen.show()
print('測試深復(fù)制----')
m3 = copy.deepcopy(m1)
print('m1:\t',m1)
m1.cpu.caculate()
m1.screen.show()
print('m3:\t',m3)
m3.cpu.caculate()
m3.screen.show()
輸出:
測試賦值----
m1:      <__main__.MobilePhone object at 0x7f8b0d6ed190>
cpu:     <__main__.CPU object at 0x7f8b0d6ed130>
screen:  <__main__.Screen object at 0x7f8b0d6ed100>
m0:      <__main__.MobilePhone object at 0x7f8b0d6ed190>
cpu:     <__main__.CPU object at 0x7f8b0d6ed130>
screen:  <__main__.Screen object at 0x7f8b0d6ed100>
測試淺復(fù)制----
m1:      <__main__.MobilePhone object at 0x7f8b0d6ed190>
cpu:     <__main__.CPU object at 0x7f8b0d6ed130>
screen:  <__main__.Screen object at 0x7f8b0d6ed100>
m2:      <__main__.MobilePhone object at 0x7f8b0d6a9940>
cpu:     <__main__.CPU object at 0x7f8b0d6ed130>
screen:  <__main__.Screen object at 0x7f8b0d6ed100>
測試深復(fù)制----
m1:      <__main__.MobilePhone object at 0x7f8b0d6ed190>
cpu:     <__main__.CPU object at 0x7f8b0d6ed130>
screen:  <__main__.Screen object at 0x7f8b0d6ed100>
m3:      <__main__.MobilePhone object at 0x7f8b0d6ed280>
cpu:     <__main__.CPU object at 0x7f8b0d6ede20>
screen:  <__main__.Screen object at 0x7f8b0d6edd30>

組合

“is-a”關(guān)系,我們可以使用“繼承”。從而實現(xiàn)子類擁有的父類的方法和屬性?!癷s-a” 關(guān)系指的是類似這樣的關(guān)系:狗是動物,dog is animal。狗類就應(yīng)該繼承動物類。

“has-a”關(guān)系,我們可以使用“組合”,也能實現(xiàn)一個類擁有另一個類的方法和屬性?!?has-a”關(guān)系指的是這樣的關(guān)系:手機擁有 CPU。 MobilePhone has a CPU。

設(shè)計模式_工廠模式實現(xiàn)

設(shè)計模式是面向?qū)ο笳Z言特有的內(nèi)容,是我們在面臨某一類問題時候固定的做法,設(shè)計 模式有很多種,比較流行的是:GOF(Goup Of Four)23 種設(shè)計模式。當(dāng)然,我們沒有 必要全部學(xué)習(xí),學(xué)習(xí)幾個常用的即可。

對于初學(xué)者,我們學(xué)習(xí)兩個最常用的模式:工廠模式和單例模式。

工廠模式實現(xiàn)了創(chuàng)建者和調(diào)用者的分離,使用專門的工廠類將選擇實現(xiàn)類、創(chuàng)建對象進行統(tǒng)一的管理和控制。

#測試工廠模式
class CarFactory():
    def creatCar(self, brand):
        if brand == '奔馳':
            return Benz()
        elif brand == '寶馬':
            return BMW()
        elif brand == '比亞迪':
            return BYD()
        else:
            print('can not create!')
class Benz():
    pass
class BMW():
    pass
class BYD():
    pass
factory = CarFactory()
c1 = factory.creatCar('奔馳')
c2 = factory.creatCar('寶馬')
c3 = factory.creatCar('比亞迪')

設(shè)計模式_單例模式實現(xiàn)

單例模式(Singleton Pattern)的核心作用是確保一個類只有一個實例,并且提供一個訪問該實例的全局訪問點。

單例模式只生成一個實例對象,減少了對系統(tǒng)資源的開銷。當(dāng)一個對象的產(chǎn)生需要比較 多的資源,如讀取配置文件、產(chǎn)生其他依賴對象時,可以產(chǎn)生一個“單例對象”,然后永久 駐留內(nèi)存中,從而極大的降低開銷。

# 測試單例模式
class MySingleton():
    __obj = None
    __init_flag = True
    def __new__(cls, *args, **kwargs):
        if cls.__obj == None:
            cls.__obj = object.__new__(cls)  # __obj對象只創(chuàng)建一次  obj對象就是Mysingleton對象
        return cls.__obj
    def __init__(self, name):
        if self.__init_flag == True:
            print('init....')
            self.name = name
            self.__init_flag = False
a = MySingleton('aa')
b = MySingleton('bb')
c = MySingleton('cc')
print(a)
print(a.name)
print(b)
print(b.name)
print(c)
print(c.name)
輸出:
init....
<__main__.MySingleton object at 0x7fce0f6e8130>
aa
<__main__.MySingleton object at 0x7fce0f6e8130>
aa
<__main__.MySingleton object at 0x7fce0f6e8130>
aa

工廠模式和單例模式的整合使用

# 測試工廠模式和單例模式的混合使用
class CarFactory():
    __obj = None
    __init_flag = True
    def __new__(cls, *args, **kwargs):
        if cls.__obj == None:
            cls.__obj = object.__new__(cls)
        return cls.__obj
    def __init__(self):
        if self.__init_flag:
            print('init factory')
            self.__init_flag = False
    
    def creatCar(self, brand):
        if brand == '奔馳':
            return Benz()
        elif brand == '寶馬':
            return BMW()
        elif brand == '比亞迪':
            return BYD()
        else:
            print('can not create!')
class Benz():
    pass
class BMW():
    pass
class BYD():
    pass
factory = CarFactory()
c1 = factory.creatCar('奔馳')
c2 = factory.creatCar('寶馬')
c3 = factory.creatCar('比亞迪')
factory2 = CarFactory()
print(factory)
print(factory2)
輸出:
init factory
<__main__.CarFactory object at 0x7fd286eecc10>
<__main__.CarFactory object at 0x7fd286eecc10>

感謝各位的閱讀!關(guān)于“Python中面向?qū)ο蟮奶卣饔心男边@篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節(jié)
AI