1. 程式人生 > 其它 >python筆記58-類裡面的__dict__屬性

python筆記58-類裡面的__dict__屬性

前言

python是面向物件的,物件有屬性和方法,可以通過__dict__檢視物件的屬性

__dict__檢視物件屬性

首先弄清楚2個概念,類(A)和類的例項物件(A()), 如下程式碼

  • count 是A的類屬性
  • name和age是 A類的例項物件A()屬性
  • start 是例項方法,預設帶self引數
  • stop 是靜態方法,可以不帶預設引數
  • open 是類方法,預設帶cls引數
class A(object):
    count = 0

    def __init__(self):
        self.name = "yoyo"
        self.age = 18

    def start(self):
        """例項方法"""
        print("start-11111")

    @staticmethod
    def stop():
        """靜態方法"""
        print("stop-22222")

    @classmethod
    def open(cls):
        print("open-3333333")

A類有屬性和方法,抽象的來講,方法也可以看成類的屬性(方法屬性)

print(A.__dict__)  # A類屬性
a = A()    # a是A類的例項物件
print(a.__dict__)   # A類的例項物件屬性

執行結果

{'__module__': '__main__', 'count': 0, '__init__': <function A.__init__ at 0x000001F84781AAE8>, 'start': <function A.start at 0x000001F84781AB70>, 'stop': <staticmethod object at 0x000001F84783A2B0>, 'open': <classmethod object at 0x000001F84783A2E8>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
{'name': 'yoyo', 'age': 18}

從執行結果可以看出,A的類屬性有count,還有定義的一些方法(__init__構造方法,還有例項方法,靜態方法,類方法)
A()例項物件只有__init__構造方法裡面的name和age屬性(count是類屬性,並不是類的例項物件屬性)

如果我們直接A.name 和 A.age就會報錯

print(A.name)
print(A.age)

報錯

Traceback (most recent call last):
  File "D:/wangyiyun_hrun3/demo/a.py", line 27, in <module>
    print(A.name)
AttributeError: type object 'A' has no attribute 'name'

因為name和age屬性在__init__構造方法裡面,只有當A類例項化的時候,才會執行__init__構造方法,這時候才會有name和age屬性了

繼承時__dict__屬性

當B類繼承A類的時候,A類和B類都有自己的類屬性 count,也各自有自己的__init__構造方法

class A(object):
    count = 0

    def __init__(self):
        self.name = "yoyo"
        self.age = 18

    def start(self):
        """例項方法"""
        print("start-11111")

    @staticmethod
    def stop():
        """靜態方法"""
        print("stop-22222")

    @classmethod
    def open(cls):
        print("open-3333333")


class B(A):
    count = 22

    def __init__(self):
        super().__init__()
        self.name = "hello"
        self.age = 22
    def new(self):
        print("new--44444")

print(A.__dict__)
print(B.__dict__)
a = A()
b = B()
print(a.__dict__)
print(b.__dict__)

執行結果

{'__module__': '__main__', 'count': 0, '__init__': <function A.__init__ at 0x000001FD03F8AAE8>, 'start': <function A.start at 0x000001FD03F8AB70>, 'stop': <staticmethod object at 0x000001FD03FAA470>, 'open': <classmethod object at 0x000001FD03FAA4A8>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
{'__module__': '__main__', 'count': 22, '__init__': <function B.__init__ at 0x000001FD03F8AD08>, 'new': <function B.new at 0x000001FD03F8AD90>, '__doc__': None}
{'name': 'yoyo', 'age': 18}
{'name': 'hello', 'age': 22}

從執行結果可以看出

  • A類和B類的類屬性count是不一樣的,
  • 雖然B類繼承了A類,方法屬性也不一樣,可以清楚的區分出哪些是A類的方法屬性,哪些是B類的方法屬性