Python 面向對象設計基礎實戰【私有成員、保護成員、公有成員、數據成員、實例化、方法】

#面向對象,基礎類
#cls 用於定義類方法,self 用於定義實例方法
class Car(object):
    def infor(self):
        print("This is a Cat!")

Irish_Moonshine = Car() #實例化一個對象
Irish_Moonshine.infor()

flag = isinstance(Irish_Moonshine, Car)#測試前者對象是否屬於後者
print(flag)

flag = isinstance(Irish_Moonshine, str)
print(flag)

TypeI = type(Irish_Moonshine) #查看類型type
print(TypeI)

#私有對象,如果成員名以兩個(或更多)下劃線開頭但是並不以兩個(或更多)
#下劃線結尾的成員變量,爲私有成員!

#但Python並沒有爲私有成員提供嚴格的訪問保護機制

class A:
    def __init__(self, value1 = 0, value2 = 0): #成員方法
        self.value1 = value1 #public
        self.value2 = value2 #public
    def setValue(self, value1, value2):
        self._value1 = value1 #protected 保護對象,只有類對象和子類對象可以訪問
        self.__value2 = value2 #private 私有對象
    def show(self):
        print(self._value1)
        print(self.__value2)


Wnqq = A() #實例化對象

print(Wnqq.value1)
#0
print(Wnqq.value2)
#0
print(dir(Wnqq))#查看Wnqq的所有公開成員
#['__class__', '__delattr__', '__dict__', 
#'__dir__', '__doc__', '__eq__', '__format__', 
#'__ge__', '__getattribute__', '__gt__', '__hash__',
#'__init__', '__init_subclass__', '__le__', '__lt__',
#'__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
#'__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
#'__weakref__', 'setValue', 'show', 'value1', 'value2']


#print(Wnqq._value1) ERROR: 'A' object has no attribute '_value1'
#print(Wnqq.__value2) ERROR: 'A' object has no attribute '__value2'
#__xx__ :系統定義的特殊成員


#對象的數據成員一般在__init__中定義


class Demo(object):
    total = 0
    def __new__(cls, *args, **lwargs):
        if cls.total >=3:
            raise Exception('最多隻創建3個對象')
        else:
            return object.__new__(cls)
    def __init__(self):
        Demo.total = Demo.total + 1

data1 = Demo()
data2 = Demo()
data3 = Demo()
#data4 = Demo() #Exception: 最多隻創建3個對象 


class zzTest:
    def __init__(self, *args, **kwargs):
        print("init")
        print(self)

    @classmethod #如果有此句子,cls只是類;否則cls和self一樣是實例化對象
#classmethod:Python裝飾器類函數,屬於整個類,類似於C++/JAVA中的靜態函數。
#類方法有類變量cls傳入,從而可以用cls做一些相關的處理。
#子類繼承時,調用該類方法時,傳入的類變量cls是子類,而非父類。
#既可以在類內部使用self訪問,也可以通過實例、類名訪問。
#即在類的函數前加@classmethod屬性,函數第一個參數爲cls類,
#表示該函數是類的方法,而不需要綁定具體實例。
#在類方法裏面可以調用類的屬性,並且在類調用該函數時,
#會將自身作爲第一個參數傳入,類方法不能訪問實例。實例可以調用類方法。


#使用@staticmethod或@classmethod,
#就可以不需要實例化,直接類名.方法名()來調用。
#這有利於組織代碼,把某些應該屬於某個類的函數給放到那個類裏去,
#同時有利於命名空間的整潔。
#Reference:https://www.jianshu.com/p/417ac7d95db9

    def Wnqq(cls):
        print("cls")
        print(cls)

test = zzTest()
test.Wnqq()
#init
#<__main__.zzTest object at 0x00000235F8A32D30>
#cls
#<class '__main__.zzTest'>
print(test.__class__)
#<class '__main__.zzTest'>
zzTest().Wnqq() #因爲@classmethod,所以可以不用實例化直接訪問Wnqq()方法
#cls
#<class '__main__.zzTest'>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章