py面向對象編程(類屬性/實例屬性/實例方法、__私有變量、繼承/多態/鴨子類型:如文件對象的read()方法、獲取對象信息:dir()/isinstance()/hasattr()等)

#py面向對象編程.py
#類屬性/實例屬性/實例方法、__私有變量、繼承/多態/鴨子類型:如文件對象的read()方法、獲取對象信息:dir()/isinstance()/hasattr()等


# =============================================================================
# #面向對象編程(類屬性/實例屬性/實例方法、__私有變量、繼承/多態)
# #面向對象的程序設計把計算機程序視爲一組對象的集合,
# #每個對象都可以接收其他對象發過來的消息,並處理這些消息,計算機程序的執行就是一系列消息在各個對象之間傳遞。
# #
# #Python中,所有數據類型都可以視爲對象,當然也可以自定義對象。即創建Class類。
# #封裝、繼承和多態是面向對象的三大特點
# =============================================================================
'''
一、類屬性 與 實例屬性 及 實例方法
1、#使用: class來創建類,後面緊接着類名(類名通常首字母大寫來區分與函數func),緊接着是(object)表示繼承於哪個類。所有類的基類都是 object
2、#使用:變量賦值來創建類實例化對象,類的的初始化方法__init__裏如果有參數,則實例化對象需要填寫參數。
3、#注意:如果刪除 實例化對象屬性 後,再次調用將會輸出 同名的類屬性。
#注意:類屬性、實例化對象屬性 的自由設置和刪除,可通過私有名稱來對其 訪問限制。


二、類的內部訪問限制(__私有變量)
#類屬性、實例化對象屬性 的自由設置和刪除,可通過私有名稱來對其 訪問限制。

1、#使用:__兩個下劃線加在屬性名稱前面使其變成私有變量,私有變量有內部可以訪問,外部不能直接訪問。
2、#使用:定義實例化方法get和set方法 來供外部 訪問和設置 私有變量方法。
#在定義方法中,可以對參數做檢查,避免傳入無效的參數

3、#注意:類對象的私有變量其實是解釋器自動更改成了 _類名__變量名 的格式。


三、繼承 和 多態/鴨子類型(如文件對象的read()方法)
1、#繼承 即可以把父類的所有功能都直接拿過來,這樣就不必重零做起,子類只需要新增自己特有的方法,也可以把父類不適合的方法覆蓋重寫。
2、#多態 即鴨子類型 及 當子類和父類都擁有相同的類方法時,相當於子類方法覆蓋了父類方法。
#多態的表現 即 動態語言的鴨子類型特點決定了繼承不像靜態語言那樣是必須的。

#鴨子類型 即只要實現了參數調用的方法就可以作爲參數來使用。例如文件對象的read()方法。

3、#使用:ininstance(obj,class_or_tuple) 來判斷 參數boj對象 是否屬於 參數2類型,返回Bool值。


四、獲取對象信息:type()/isinstance()/dir()/hasattr()、getattr()、setattr()
1、#使用:type(obj_or_name) 來獲取對象類型
2、#使用:ininstance(obj,class_or_tuple) 來判斷 參數boj對象 是否屬於 參數2類型,返回Bool值。

3、#使用:dir(obj) 來返回一個對象的所有屬性和方法。
#注意:類似__XXX__這樣的屬性和方式是有特殊用途的,稱爲魔法屬性、魔法方法。
#比如__len__方法返回長度,即a.__len__等同於len(a)
#普通屬性和方法如 'ABC'.lower() 返回小寫

4、#使用:hasattr(obj,'name')判斷參數obj是否含有name屬性或方法
5、#使用:getattr(obj,'name',value)獲取參數obj對象的name屬性,如果不存在則輸出參數value
6、#使用:setattr(obj,'name',value)設置參數obj對象的name屬性爲參數value
#注意:參數name爲字符串類型

7、#使用:hasattr(obj,'open') 來判斷fp對象是否存在read方法,
#如果存在,則該對象是一個流,如果不存在,則無法讀取。


'''



#################### 類屬性 與 實例屬性 及 實例方法
#使用: class來創建類,後面緊接着類名(類名通常首字母大寫來區分與函數func),緊接着是(object)表示繼承於哪個類。所有類的基類都是 object

#使用:變量賦值來創建類實例化對象,類的的初始化方法__init__裏如果有參數,則實例化對象需要填寫參數。

#注意:如果刪除 實例化對象屬性 後,再次調用將會輸出 同名的類屬性。
#注意:類屬性、實例化對象屬性 的自由設置和刪除,可通過私有名稱來對其 訪問限制。


#使用: class來創建類,後面緊接着類名(類名通常首字母大寫來區分與函數func),緊接着是(object)表示繼承於哪個類。所有類的基類都是 object
class Student(object):          
    name='Stud'                       #類屬性
    def __init__(self):               #通過參數self來指定該方法爲實例化對象方法
        """初始化方法,通過self參數來指定 構建實例化對象的屬性
        如果初始化方法內加上屬性,則實例化對象時需要傳入參數,否則報錯
        """
        self.name='xiaoxiao'          #實例化屬性
#        score=100                    #如果變量前不指定self,則此非實例化屬性 
    def print_score(self):            #通過參數self來指定該方法爲實例化對象方法
        print('%s: %s' %(self.name, self.score))
Student.name                          #輸出類名稱
Student.name='aaaa'                   #賦值修改類屬性名稱
Student.name                        

#使用:變量賦值來創建類實例化對象,類的的初始化方法__init__裏如果有參數,則實例化對象需要填寫參數。
s=Student('小王',99)                  #創建實例化對象
s.name                                #輸出實例化對象屬性
s.name='xiaowang'                     #賦值設置實例化對象屬性
s.name                       

b=Student('小張',98)
b.name
b.print_score()                       #調用實例化對象方法

#注意:如果刪除 實例化對象屬性 後,再次調用將會輸出 同名的類屬性。
#注意:類屬性、實例化對象屬性 的自由設置和刪除,可通過私有名稱來對其 訪問限制。
del b.name                     
b.name




#################### 類的內部訪問限制(__私有變量)
#類屬性、實例化對象屬性 的自由設置和刪除,可通過私有名稱來對其 訪問限制。

#使用:__兩個下劃線加在屬性名稱前面使其變成私有變量,私有變量有內部可以訪問,外部不能直接訪問。

#使用:定義實例化方法get和set方法 來供外部 訪問和設置 私有變量方法。
#在定義方法中,可以對參數做檢查,避免傳入無效的參數

#注意:類對象的私有變量其實是解釋器自動更改成了 _類名__變量名 的格式。


#使用:__兩個下劃線加在屬性名稱前面使其變成私有變量,私有變量有內部可以訪問,外部不能直接訪問。
class Student(object):
    def __init__(self, name, score):
        """類屬性、實例化對象屬性 的自由設置和刪除,可通過私有名稱來對其 訪問限制。
        使用:__兩個下劃線加在屬性名稱前面使其變成私有變量,
        私有變量只有內部可以訪問,外部不能直接訪問。"""
        self.__name= name
        self.__score= score
    def print_score(self):
        print('%s: %s' %(self.__name,self.__score))

bart=Student('Bart Simpson',59)
#bart.__name                         #外部訪問__私有變量將會異常。


#使用:定義實例化方法get和set方法 來供外部 訪問和設置 私有變量方法。
#在定義方法中,可以對參數做檢查,避免傳入無效的參數
class Student(object):
    def __init__(self, name, score):
        self.__name=name
        self.__score=score
    """定義get方法來供外部訪問屬性 """
    def get_name(self):
        return self.__name
    def get_score(self):
        return self.__score
    """定義set方法來供外部設置屬性"""
    def set_name(self,name):
        self.__name=name
    def set_score(self,score):
        """#在定義方法中,可以對參數做檢查,避免傳入無效的參數"""
        if 0<=score<=100:
            self.__score=score
        else:
            raise ValueError('成績輸入有誤(0-100)')
bart=Student('Bart Simpson',1000)
bart.get_name()
bart.get_score()

bart.set_name('ddd')
bart.get_name()

bart.set_score(101)    #超出參數設定,引發異常

#注意:類對象的私有變量其實是解釋器自動更改成了 _類名__變量名 的格式。
#bart.__name           #私有變量外部不可訪問
bart._Student__name    #私有變量名稱其實是解釋器自動更改成了 _類名__變量名 的格式。





#################### 繼承 和 多態/鴨子類型(如文件對象的read()方法)
#繼承 即可以把父類的所有功能都直接拿過來,這樣就不必重零做起,子類只需要新增自己特有的方法,也可以把父類不適合的方法覆蓋重寫。

#多態 即鴨子類型 及 當子類和父類都擁有相同的類方法時,相當於子類方法覆蓋了父類方法。
#多態的表現 即 動態語言的鴨子類型特點決定了繼承不像靜態語言那樣是必須的。

#鴨子類型 即只要實現了參數調用的方法就可以作爲參數來使用。例如文件對象的read()方法。

#使用:ininstance(obj,class_or_tuple) 來判斷 參數boj對象 是否屬於 參數2類型,返回Bool值。




#####繼承
class Animal(object):
    def run(self):
        print('Animal is running...')
class Dog(Animal):
    """繼承 即 可以把父類的所有功能都直接拿過來,這樣就不必重零做起"""
    pass
class Cat(Animal):
    """子類只需要新增自己特有的方法,也可以把父類不適合的方法覆蓋重寫"""
    def run(self):
        print('Cat is running...')
dog=Dog() 
cat=Cat()
dog.run() 
cat.run()

#使用:ininstance(obj,class_or_tuple) 來判斷 參數boj對象 是否屬於 參數2類型,返回Bool值。
help(isinstance)
isinstance(dog,Dog)      #dog屬於Dog類
isinstance(dog,Animal)   #dog屬於Animal類
isinstance(Animal,Cat)   #Animal不屬於Cat類


#####多態
def run_twice(animal):
    """定義一個函數,執行兩次參數對象的run()方法。
    即:參數爲一個對象,該參數對象需要具備run方法"""
    animal.run()
    animal.run()
run_twice(Animal())
run_twice(cat)
run_twice(Cat())
"""#鴨子類型 即只要實現了參數調用的方法就可以作爲參數來使用。例如文件對象的read()方法。"""
class Timer():
    def run(self):
        print('Start...')
run_twice(Timer())




#################### 獲取對象信息:type()/isinstance()/dir()/hasattr()、getattr()、setattr()
#使用:type(obj_or_name) 來獲取對象類型
#使用:ininstance(obj,class_or_tuple) 來判斷 參數boj對象 是否屬於 參數2類型,返回Bool值。

#使用:dir(obj) 來返回一個對象的所有屬性和方法。
#注意:類似__XXX__這樣的屬性和方式是有特殊用途的,稱爲魔法屬性、魔法方法。
#比如__len__方法返回長度,即a.__len__等同於len(a)
#普通屬性和方法如 'ABC'.lower() 返回小寫

#使用:hasattr(obj,'name')判斷參數obj是否含有name屬性或方法
#使用:getattr(obj,'name',value)獲取參數obj對象的name屬性,如果不存在則輸出參數value
#使用:setattr(obj,'name',value)設置參數obj對象的name屬性爲參數value
#注意:參數name爲字符串類型

#使用:hasattr(obj,'open') 來判斷fp對象是否存在read方法,
#如果存在,則該對象是一個流,如果不存在,則無法讀取。



#####
#使用:type(obj_or_name) 來獲取對象類型
type(123)
type('str')
type(object)
type(None)
type(abs)


#####
#使用:ininstance(obj,class_or_tuple) 來判斷 參數boj對象 是否屬於 參數2類型,返回Bool值。
help(isinstance)
isinstance(dog,Dog)      #dog屬於Dog類
isinstance(dog,Animal)   #dog屬於Animal類
isinstance(Animal,Cat)   #Animal不屬於Cat類
#能用type()判斷的基本類型也可以用isinstance()判斷:
isinstance('str',str)
#還可以判斷是某些類型的一種
isinstance([1,2,3,4],(list,tuple))


#####
#使用:dir(obj) 來返回一個對象的所有屬性和方法。
#如dir(str)獲取str的所有屬性和方法
dir(str)
dir('123')
dir(Cat)    

#注意:類似__XXX__這樣的屬性和方式是有特殊用途的,稱爲魔法屬性、魔法方法。
#比如__len__方法返回長度,即a.__len__等同於len(a)
#普通屬性和方法如 'ABC'.lower() 返回小寫
'ABC'.lower()


#####
#使用:hasattr(obj,'name')判斷參數obj是否含有name屬性或方法
#使用:getattr(obj,'name',value)獲取參數obj對象的name屬性,如果不存在則輸出參數value
#使用:setattr(obj,'name',value)設置參數obj對象的name屬性爲參數value
#注意:參數name爲字符串類型

help(hasattr)
help(getattr)
help(setattr)

class MyObject(object):
    def __init__(self):
        self.x=9
    def power(self):
        return self.x * self.x
obj=MyObject()

hasattr(obj,'x')      #返回True
hasattr(obj,'power')  #返回True
hasattr(obj,'y')      #返回False

getattr(obj,'x')
getattr(obj,'y',10)   #如果沒有y屬性和方法則輸出參數10

setattr(obj,'y',11)
getattr(obj,'y')

#如果可以直接寫:
sum = obj.x + obj.y
sum
#就不要寫:
sum = getattr(obj, 'x') + getattr(obj, 'y')
sum


#使用:hasattr(obj,'open') 來判斷fp對象是否存在read方法,
#如果存在,則該對象是一個流,如果不存在,則無法讀取。
hasattr(obj,'open')










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