二:面向對象 類和對象

一:對象的 加載順序

class A:
    country = 'China'
    print(country)          # China
    def __init__(self):
        print('執行我了')

A.country = 'English'        # China



類的加載順序
  1.類內部一個縮進的全部代碼都是在py文件從上到下解釋的時候就已經被執行了
  2.類中的代碼永遠是從上到下依次執行的,不須要調用
  3.若是有同名的方法、屬性,老是寫在後面的會生效

    
class A:
    country = 'China'
    def __init__(self):
        print('執行我了')   # 執行我了

    def func(self):
        print('1111111')

    def func(self):
        print('2222222')    # 2222222   只打印2222222,不打印1111111
                           # 若是有同名的方法、屬性,老是寫在後面的會生效

A.country = 'English'
a = A()                 # 執行我了
a.func()                # 2222222


 

class A:
    country = 'China'
    country = 'English'
    def __init__(self):
        print('執行我了')       # 執行我了

    def func(self):
        print('1111111')

    def func(self):
        print('2222222')    # 2222222 只打印2222222,不打印1111111


print(A.country)            # English




class A:
    def __init__(self):
        print('執行我了')   # 執行我了

    def func(self):
        print('1111111')

    def func(self):
        print('2222222',A.country)  # 2222222 English

    country = 'China'
    country = 'English'

# a = A()  # 實例化一個對象
# a.func()

A().func() # 對象調用函數
class A:
    wahaha = 'adGa'
    def wahaha(self):
        pass
print(A.wahaha)     # <function A.wahaha at 0x00000178CB465730>
a = A()
print(a.wahaha)
# <bound method A.wahaha of <__main__.A object at 0x00000178CB2C7358>>
# wahaha方法把變量給覆蓋了,就是後加載進來的方法覆蓋了以前加載的屬性

class A:
    wahaha = 'adGa'
    def t(self):
        pass
print(A.wahaha)     # adGa
print(A().wahaha)   # adGa


一:咱們定義的類的屬性到底存到哪裏了?有兩種方式查看
dir(類名):查出的是一個名字列表
類名.__dict__:查出的是一個字典,key爲屬性名,value爲屬性值

二:特殊的類屬性
類名.__name__     # 類的名字(字符串)
類名.__doc__      # 類的文檔字符串
類名.__base__     # 類的第一個父類(在講繼承時會講)
類名.__bases__    # 類全部父類構成的元組(在講繼承時會講)
類名.__dict__     # 類的字典屬性
類名.__module__   # 類定義所在的模塊
類名.__class__    # 實例對應的類(僅新式類中)

二:類和對象的命名空間

類 和 對象 存儲在兩塊命名空間裏的
class Student:
    country = 'China'
    def __init__(self,name,country):
        self.name = name
        self.country = country

zhang = Student('Ivan','日本人')
zou = Student('Jone','法國人')
print(Student.country)  # China
print(zou.country)  # 法國人
print(zhang.country)    # 日本人

# 對象去找類空間中的名字的前提 : 在本身的空間中沒有這個名字


class Student:
    country = 'China'
    def __init__(self,name):
        self.name = name

zhang = Student(''Ivan ')
zou = Student(' Jone ')
print(zhang.country)        # China
Student.country = '法國人'
print(zhang.country)        # 法國人
zhang.country = '日本人'   # 給一個對象添加了一個屬性
print(zou.country)      # 法國人
print(zhang.country)        # 日本人
在操做靜態變量的時候應該儘可能的使用類名來操做而不是使用對象名


人物
class Person:
    money = 0
    def __init__(self,name):
        self.name = name

    def salary_deliery(self):
        Person.money += 1000
練習 :寫一個類,可以自動的統計這個類有多少個對象

class A:
    Count = 0
    def __init__(self,name):
        self.name = name
        A.Count += 1   # 不推薦在類的內部使用類的名字

a = A('alex')           # 建立了一個新對象
a2 = A('alex2')
print(A.Count)      # 2




class B:
    a = [0]
    def __init__(self,name):
        self.name = name
b1 = B('Ivan')
b2 = B('Merry')
print(B.a)      # [0]
print(b1.a)     # [0]
print(b2.a)     # [0]

b1.a[0] += 1
print(b2.a[0])  # 1
b1.a = [123]
print(b2.a)     # [1]


只要是對一個對象.名字直接賦值,那麼就是在這個對象的空間內建立了新的屬性
只要是對一個可變的數據類型內部的變化,那麼仍然是全部的對象和類共享這個改變的成果     
b1.a[0] += 1

全部的靜態變量都是用類名來操做,這樣修改就能被全部的對象感知到
若是是對於可變數據類型的靜態變量 操做的是這個數據內部的內容,也可使用對象來調用

類的命名空間 是在定義類的階段被加載進來的:

        靜態變量、類變量 —— 直接定義在類中的變量
        動態變量、方法 —— 定義在類中的函數
        魔術方法、雙下方法
            內置的方法 :__init__
            內置的變量 : __dict__

對象的命名空間  實例化的時候建立出來的:
        類指針、類對象指針 執行init以前就已經在了
        對象的屬性   是在執行init以及以後被添加的

1,執行完init裏面的內容之後,才把student指向內存地址,至關於給內存一個命名,
student不先指向內存,是由於還不知道這塊內存有多大,若是先命名了,在加一個屬性,修改會比較麻煩

2,執行第7步init以前,偷偷的新開了一個對象的內存(每一個對象都會有本身各自的命名空間),而後執行第7步init,self指向新開的內存

3,最後才把對象的內存空間,交給yang

4,yang.func() 先找到本身的對象內存空間,每一個對象的內存 空間都會有類對象指針,類對象指針指向類。最後找到類中定義的fun

5,每一個對象都共享類裏的內容,可是內找不到對象,內裏沒有指向對象的指針
相關文章
相關標籤/搜索