天天看點

python學習進階篇(part7)--特殊屬性和特殊方法

學習筆記,僅供參考,有錯必糾

文章目錄

  • ​​python 學習進階篇​​
  • ​​特殊屬性和特殊方法​​
  • ​​擷取對象的資訊之特殊屬性`__dict__`​​
  • ​​擷取對象的資訊之反射​​
  • ​​類對象的特殊方法`__len__()`​​

python 學習進階篇

# 支援多行輸出
from IPython.core.interactiveshell import InteractiveShell 
InteractiveShell.ast_node_interactivity = 'all' #預設為'last'      

特殊屬性和特殊方法

調用内置函數dir()後的傳回值中,很多屬性和方法都是以雙下劃線​

​__​

​開頭和結尾的,這些屬性和方法中的絕大多數都繼承自類object.

以雙下劃線​

​__​

​​開頭和結尾的屬性被稱為特殊屬性,以雙下劃線​

​__​

​​開頭和結尾的方法被稱為特殊方法。特殊屬性和特殊方法都是系統預定義的,我們自定義的屬性名和方法名不要以雙下劃線​

​__​

​​開頭和結尾。在我們自定義類對象時,經常會重寫一個或多個特殊方法,例如​

​__init__​

​。特殊方法會在特定的情形下被自動調用,很少需要手動調用特殊方法。

print(dir(object))      
['__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__']      

擷取對象的資訊之特殊屬性​

​__dict__​

對于指定的類對象或執行個體對象,可以通路特殊屬性​

​__dict__​

​獲得該類對象或執行個體對象所綁定的所有屬性和方法的字典。

其中,字典中的鍵為屬性名或方法名。

class MyClass(object):
    ca = 'ca'
    
    def __init__(self):
        self.ia = 'ia'
    
    def im(self):
        pass
    
    @classmethod
    def cm(cls):
        pass
    
    @staticmethod
    def sm():
        pass

MyClass.ca2 = 'ca2'
print(MyClass.__dict__)      
{'__module__': '__main__', 'ca': 'ca', '__init__': <function MyClass.__init__ at 0x0000019632EE58C8>, 'im': <function MyClass.im at 0x0000019632EE5950>, 'cm': <classmethod object at 0x0000019632EEE3C8>, 'sm': <staticmethod object at 0x0000019632EEE438>, '__dict__': <attribute '__dict__' of 'MyClass' objects>, '__weakref__': <attribute '__weakref__' of 'MyClass' objects>, '__doc__': None, 'ca2': 'ca2'}      
mc = MyClass()
mc.ia2 = 'ia2'
print(mc.__dict__)      
{'ia': 'ia', 'ia2': 'ia2'}      

擷取對象的資訊之反射

所謂’反射’,指的是以字元串的形式來操作(包括:增删改查)對象的屬性和方法。

python學習進階篇(part7)--特殊屬性和特殊方法
class MyClass(object):
    def __init__(self):
        self.x = 1

    def do_sth(self):
        print("do_sth被調用")

mc = MyClass()

print(hasattr(mc, 'x'))         
print(hasattr(mc, 'do_sth'))    
print(hasattr(mc, 'y'))       

print(getattr(mc, 'x'))     

f = getattr(mc, 'do_sth')
f() 

# print(getattr(mc, 'y')) 
print(getattr(mc, 'y', 2))  

setattr(mc, 'z', 3)
print(getattr(mc, 'z'))

setattr(mc, 'z', 4)
print(getattr(mc, 'z')) 

delattr(mc, 'z')
print(hasattr(mc, 'z'))      
True
True
False
1
do_sth被調用
2
3
4
False      

類對象的特殊方法​

​__len__()​

# 内置函數len()用于傳回對象的長度
print(len([1, 2, 3, 4, 5])) 
print(len('abcde'))         
print(len({'a': 1, 'b': 2, 'c': 3}))      
5
5
3      

在上面的例子中,内置函數len()的實參都是内置類對象的執行個體對象,例如:

[1, 2, 3, 4, 5] 是内置類對象list的一個執行個體對象;

{‘a’: 1, ‘b’: 2, ‘c’: 3} 是内置類對象dict的一個執行個體對象。

# 内置函數len()的實參在預設情況下不能是自定義類對象的執行個體對象。
class MyClass(object):
    pass

print(len(MyClass())) # object of type 'MyClass' has no len()      
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-14-ecf26a5a6c12> in <module>()
      3     pass
      4 
----> 5 print(len(MyClass()))


TypeError: object of type 'MyClass' has no len()      

如果想讓内置函數len()的實參可以是自定義類對象的執行個體對象,必須在自定義類對象中實作特殊方法​

​__len__()​

​​。這樣,調用内置函數len()時,在其内部會自動調用實參所對應類對象的特殊方法​

​__len__()​

​​。之是以内置函數len()的實參可以是上述内置類對象的執行個體對象,是因為上述的内置類對象中都實作了特殊方法​

​__len__()​

​.

class MyClass(object):
    def __len__(self):
        return 18

print(len(MyClass()))