Python OOP-4

8. 類的成員描述符(屬性)

  • 類的成員描述是為了在類中對類的成員屬性進(jìn)行相關(guān)操作而創(chuàng)建的一種方式
    • get:獲取屬性的操作
    • set:修改或添加屬性操作
    • delete:刪除屬性的操作
  • 如果想使用類的額成員描述符,大概有三種方法
    • 使用類實(shí)現(xiàn)描述器
    • 使用屬性修飾符
    • 使用property函數(shù)
      • property函數(shù)很簡單
      • property(fget, fset, fdel, doc)
  • 無論哪種修飾符都是為了對成員屬性進(jìn)行相應(yīng)的控制
    • 類的方式:適用多個(gè)類中的多個(gè)屬性共用同一個(gè)描述符
    • property:適用當(dāng)前類中使用,可以控制一個(gè)類中多個(gè)屬性
    • 屬性修飾符:適用于當(dāng)前類中使用,控制一個(gè)類中的一個(gè)屬性

9. 類的內(nèi)置屬性

    __dict__: 以字典的方式顯示類的成員組成
    __doc__: 獲取類的文檔信息
    __name__: 獲取類的名稱,如果在模塊中使用,獲取模塊的名稱
    __bases__: 獲取某個(gè)類的所有父類,以元組的方式顯示

10. 類的常用魔術(shù)方法

  • 魔術(shù)方法就是不需要人為調(diào)用的方法,基本是在特定的時(shí)間自動(dòng)觸發(fā)
  • 魔術(shù)方法的統(tǒng)一特征,方法名被前后各兩個(gè)下劃線包裹
  • 操作類
    • __init__:構(gòu)造函數(shù)
    • __new__:對象實(shí)例化方法,此魔術(shù)方法較特殊,一般不需要使用
    • __call__:對象當(dāng)函數(shù)使用的時(shí)候觸發(fā)
    • __str__:當(dāng)對象被當(dāng)作字符串使用的時(shí)候
    • __repr__:返回字符串
  • 描述符相關(guān)
    • __set__
    • __get__
    • __delete__
  • 屬性操作相關(guān)
    • __getattr__:訪問一個(gè)不存在的屬性時(shí)觸發(fā)
    • __setattr__:對成員屬性進(jìn)行設(shè)置的時(shí)候觸發(fā)
      • 參數(shù):
        • self用來獲取當(dāng)前對象
        • 被設(shè)置的屬性名稱,以字符串形式出現(xiàn)
        • 需要對屬性名稱設(shè)置的值
      • 作用:進(jìn)行屬性設(shè)置的時(shí)候進(jìn)行驗(yàn)證或者修改
      • 注意:在該方法中不能對屬性進(jìn)行賦值操作,否則死循環(huán)
  • 運(yùn)算類相關(guān)魔術(shù)方法
    • __gt__:進(jìn)行大于判斷的時(shí)候觸發(fā)的函數(shù)
      • 參數(shù)
        • self
        • 第二個(gè)參數(shù)是第二個(gè)對象
        • 返回值可以是任意值,推薦返回布爾值

11. 類和對象的三種方法

  • 實(shí)例方法
    • 需要實(shí)例化對象才能使用的方法,使用過程中可能需要截至對象的其他對象的方法完成
  • 靜態(tài)方法
    • 不需要實(shí)例化,通過類直接訪問
  • 類方法
    • 不需要實(shí)例化
# 屬性案例
# 創(chuàng)建Student類,描述學(xué)生類
# 學(xué)生具有Student.name屬性
# 但name格式并不統(tǒng)一
# 可以用增加一個(gè)函數(shù),然后自動(dòng)調(diào)用的方式,但很蠢
class Student():
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
        # 如果不想修改代碼
        self.setName(name)
        
    # 介紹下自己
    def intro(self):
        print("Hai, my name is {0}".format(self.name))
        
    def setName(self, name):
        self.name = name.upper()
        
s1 = Student("RUO Chen", 19.8)
s2 = Student("michi stangle", 24.0)
s1.intro()
s2.intro()
Hai, my name is RUO CHEN
Hai, my name is MICHI STANGLE
# propertya 案例
# 定義一個(gè)Person類,具有name,age屬性
# 對于任意輸入的姓名,我們希望用大寫方式保存
# 年齡,我們希望內(nèi)部統(tǒng)一用整數(shù)保存
# x = property(fget, fset, fdel, doc)
class Person():
    '''
    這是一個(gè)人,一個(gè)高尚的人,一個(gè)脫離了低俗趣味的人
    他還他媽的有屬性
    '''
    # 函數(shù)名稱可以任意
    def fget(self):
        return self._name * 2
    
    def fset(self, name):
        # 所有輸入的姓名以大寫方式 保存
        self.name = name.upper()
    def fdel(self):
        self._name = "NoName"
        
    name = property(fget, fset, fdel, "對name進(jìn)行操作")
# 類的內(nèi)置屬性舉例
print(Person.__dict__)
print(Person.__doc__)
print(Person.__name__)
# 元組形式顯示所有的父類
print(Person.__bases__) 
{'__module__': '__main__', '__doc__': '\n    這是一個(gè)人,一個(gè)高尚的人,一個(gè)脫離了低俗趣味的人\n    他還他媽的有屬性\n    ', 'fget': <function Person.fget at 0x000001FBBD3AFBF8>, 'fset': <function Person.fset at 0x000001FBBD3AF9D8>, 'fdel': <function Person.fdel at 0x000001FBBD3AF8C8>, 'name': <property object at 0x000001FBBD3B7BD8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>}

    這是一個(gè)人,一個(gè)高尚的人,一個(gè)脫離了低俗趣味的人
    他還他媽的有屬性
    
Person
(<class 'object'>,)
# init 舉例
class A():
    def __init__(self, name = 0):
        print("哈哈,我被調(diào)用了")
        
a = A()
哈哈,我被調(diào)用了
# __call__ 舉例
class A():
    def __init__(self, name = 0):
        print("哈哈,我被調(diào)用了")
        
    def __call__(self):
        print("我被調(diào)用again")
        
a = A()
a()
哈哈,我被調(diào)用了
我被調(diào)用again
# __str__ 舉例
class A():
    def __init__(self, name = 0):
        print("哈哈,我被調(diào)用了")
        
    def __call__(self):
        print("我被調(diào)用again")
        
    def __str__(self):
        return '666'
        
a = A()
print(a)
哈哈,我被調(diào)用了
666
# __getattr__
class A():
    name = "NoName"
    age = 18
    
    def __getattr__(self, name):
        print("沒找到")
        print(name)
    

        
a = A()
print(a.name)
print(a.addr)
NoName
沒找到
addr
None
# __setattr__ 案例
class Person():
    def __init__(self):
        pass
    
    def __setattr__(self, name, value):
        print("設(shè)置屬性:{0}".format(name))
        # 下面語句會(huì)導(dǎo)致問題,死循環(huán)
        # self.name = value
        # 此種情況,為了避免死循環(huán),規(guī)定統(tǒng)一調(diào)用父類魔法函數(shù)
        super().__setattr__(name, value)
p = Person()
print(p.__dict__)
p.age = 18
{}
設(shè)置屬性:age
# __gt__

class Student():
    def __init__(self, name):
        self._name = name
        
    def __gt__(self, obj):
        print("哈哈,{0} 會(huì)比 {1} 大嗎?".format(self, obj))
        return self._name > obj._name
    
stu1 = Student("one")
stu2 = Student("two")
print(stu1 > stu2)
哈哈,<__main__.Student object at 0x000001C15772EB38> 會(huì)比 <__main__.Student object at 0x000001C15772E550> 大嗎?
False
# 三種方法的案例
class Person():
    # 實(shí)例方法
    def eat(self):
        print(self)
        print("Eating......")
    # 類方法
    # 類方法的第一個(gè)參數(shù),一般命名為cls,區(qū)別于self
    @classmethod
    def play(cls):
        print(cls)
        print("Playing......")
        
    # 靜態(tài)方法
    # 不需要用第一個(gè)參數(shù)表示自身或者類
    @staticmethod
    def say():
        print("Saying......")
        
yueyue = Person()

# 實(shí)例方法
yueyue.eat()
# 類方法
Person.play()
yueyue.play()
# 靜態(tài)方法
Person.say()
yueyue.say()
<__main__.Person object at 0x000001C157766710>
Eating......
<class '__main__.Person'>
Playing......
<class '__main__.Person'>
Playing......
Saying......
Saying......
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容