1. 程式人生 > >Python入門學習筆記————11 (類與物件)

Python入門學習筆記————11 (類與物件)

class Student ():
    name = 'goudan'
    age = 18
 
Student.__dict__
goudan = Student()
goudan.__dict__

Out[38]:

{}

類和物件的成員分析

  • 類和物件都可以儲存成員,成員可以歸類所有也可以歸物件所有
  • 類儲存成員時使用的是與類關聯的一個物件
  • 獨享儲存成員是儲存在當前的物件中
  • 物件訪問一個成員時,如果物件中沒有該成員,嘗試訪問類中的同名成員,如果物件中有此成員,一定使用物件中的成員
  • 建立物件的時候,類中的成員不會放入物件中,而是得到一個空物件,沒有成員
  • 通過物件對類中成員重新賦值或者通過物件新增成員時,對應成員會儲存在物件中,而不會修改類成員

In [33]:

 

class A ():
    name = 'goudan'
    age = 18
    #注意say的寫法,引數有一個self
    def say(self):
        self.name='aaa'
        self.age=20
 
#此案例說明,類例項的屬性和物件的例項屬性在不對物件的例項屬性賦值的前提下,指向同一個變數        
#此時A稱為類例項
print(A.name)
print(A.age)
print('#'*20)
print(id(A.name))
print(id(A.age))
print('#'*20)
a = A()
print(a.name)
print(a.age)
print(id(a.name))
print(id(a.age))
goudan
18
####################
139958490438376
94215097638656
####################
goudan
18
139958490438376
94215097638656

In [39]:

 

print(A.name)
print(A.age)
print('#'*20)
print(id(A.name))
print(id(A.age))
print('#'*20)
a = A()
#檢視A內所有的屬性
print(A.__dict__)
print('#'*20)
#賦值前檢視屬性
print(a.__dict__)
print('#'*20)
#對例項物件賦值並檢視屬性
a.name = 'pidan'
a.age = 10
print(a.__dict__)
print(a.name)
print(a.age)
print(id(a.name))
print(id(a.age))
goudan
18
####################
139958490438376
94215097638656
####################
{'__module__': '__main__', 'name': 'goudan', 'age': 18, 'say': <function A.say at 0x7f4aa00b5730>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
####################
{}
####################
{'name': 'pidan', 'age': 10}
pidan
10
139958489651832
94215097638400

關於self

  • self 在物件方法中表示物件本身,如果通過物件呼叫一個方法,那麼該物件會自動傳入到當前方法的第一個引數
  • self本身不是關鍵字,只是一個用於接受物件的普通引數,理論上可以用任何普通變數名代替
  • 方法中有self形參的方法成為非繫結類的方法,可以通過物件訪問,沒有self的繫結類的方法,只能通過類訪問
  • 使用類訪問繫結類的方法時,如果類方法中需要訪問當前類的成員,可以通過class成員名來訪問

In [44]:

 

 
class Student ():
    name = 'goudan'
    age = 18
    #注意say的寫法,引數有一個self,self本身不是關鍵字,可以更換為其他
    def Homework(self):
        self.name='aaa'
        self.age=20
        print('my name is {0}'.format(self.name))
        print('I am {0} years old'.format(self.age))
goudan = Student()
goudan.Homework()
my name is aaa
I am 20 years old

In [56]:

 

class Teacher ():
    name = 'goudan'
    age = 18
    def say(self):
        self.name = 'haha'
        self.age = 20
        print('my name is {0}'.format(self.name))
        print('I am {0} years old'.format(self.age))
        #呼叫類成員時需要使用__class__
        print('I am {0} years old'.format(__class__.age))
    def good():
        #訪問類裡面的成員
        print(__class__.name)
        print(__class__.age)
        #
        print('see you again')
t = Teacher()
t.say()
#呼叫繫結引數需要使用類名
Teacher.good()
my name is haha
I am 20 years old
I am 18 years old
goudan
18
see you again

In [58]:

 

# 關於self的案例
class A ():
    name = 'goudan'
    age = 18
    #建構函式
    def __init__(self):
        self.name = 'aaa'
        self.age=20
    def say(self):
        print(self.name)
        print(self.age)
class B ():
    name = 'bbb'
    age = 30
 
a = A()
#系統預設傳入a
a.say()
#傳入引數為a
A.say(a)
##傳入引數為A
A.say(A)
#此時傳入的是類例項B,因為B具有name和age屬性,所以不會報錯
A.say(B)
#以上例子使用鴨子模型     
aaa
20
aaa
20
goudan
18
bbb
30

面向物件的三大特徵

封裝

  • 封裝就是對物件的成員進行訪問限制
  • 三個級別
    • 公開 public
    • 受保護的 protected
    • 私有的 private
    • public,protectde,private不是關鍵字
  • 判別物件位置
    • 物件內部
    • 物件外部
    • 子類中
  • 私有
    • 私有成員是最高階的封裝,只能在當前類或物件中訪問
    • 私有成員前新增兩個下劃線即可 class Person():
        #name為公有成員
        name = 'haha'
        #__age為私有成員
        __age = 18
      
    • Python的私有不是正的私有,是一種成為name mangling的改名策略,可以使用 .classnameattributename訪問 /注意案例

      繼承

      多型

In [60]:

 

#私有例項
class Person():
    #name為公有成員
    name = 'haha'
    #__age為私有成員
    __age = 18
p = Person()
print(p.name)
#注意報錯資訊
print(p.__age)
haha
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-60-21f97a098560> in <module>()
      7 print(p.name)
      8 #注意報錯資訊
----> 9 print(p.__age)

AttributeError: 'Person' object has no attribute '__age'

In [62]:

 

#name mangling技術
print(Person.__dict__)
{'__module__': '__main__', 'name': 'haha', '_Person__age': 18, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}

In [64]:

 

#注意上述函式執行結果中的age,通過此命令可以訪問私有(即被更改命名的)成員
print(p._Person__age)
18