我的Python學習之路05-附練習題

面向對象思想

面向對象編程

  • 類class與對象object
  • 對屬於同一類事物的抽象叫類class
    • 比如汽車,門,貓。
    • 之前學習使用的都是Python自帶的數據類,這節課我們學習自己定義類class
  • 某類事物中的一個具體的實例叫對象Object
    • 比如我家的那輛汽車,張偉辦公室的大門,隔壁麗麗家的那隻小花貓。
  • 類與對象的關係
  • 類定義封裝了數據與方法,類就是對象的模板,可以批量生產出許多的對象。
    • 比如a=7,7其實是整形數字int類的一個實例。那int這個類還可以’復刻’出許許多多的整形對象。這些對象共有的特徵就是:整數性。
  • 類(class)的變量是所有對象共享使用, 只有一個拷貝, 所有對象修改, 都可以被其他對象所見;
  • 對象(object)的變量由類的每個對象所擁有, 每個對象都包含自己的一份拷貝, 不會影響其他對象;

Python中一切皆對象

#Python中的一切對象都可以使用type查看它的類
#isinstance,issubclass的使用
class Animal():
    pass

class Cat(Animal):
    pass

c = Cat()

#isinstance判斷一個對象實例是否屬於該類型,但是isinstance的判斷沒有type準確,它無法判斷子類的對象和父類的關係
print(isinstance(c, Cat))  # c是一隻貓
print(isinstance(c, Animal))  # 向上判斷 c是一隻動物
print(type(c) is Cat)
print(type(c) is Animal)

#issubclass判斷給定的兩個類,前者是否是後者的子類
print('\n')
print(issubclass(Cat, Animal))  # 判斷Cat類是否是Animal類的子類
print(issubclass(Animal, Cat))  # 判斷Animal類是否是Cat類的子類

輸出結果爲:

True
True
True
False

True
False

類的設計與創建

#學生類設計
#總學生的人數,全部學生的姓名,已經畢業的學生的數量
#考試功能,分數大於60分,pass,,計入總分,否則 fail
#查分功能,如果考試次數
#查所有已經畢業學員的姓名。


class Student():
    student_total = 0
    student_graduated=0
    student_namelist=[]
    student_graduated_name_list=[]
    
    def __init__(self,name,age,gender):
        self.name=name
        self.age=age
        self.gender=gender
        self.__score=0
        self.times=0#考試次數
        Student.student_total+=1
        Student.student_namelist.append(name)

    def exam(self,examscore):#def函數在類中定義叫方法method,以和類外部定義的函數區分
        if self.times==8:
            return 'you already qualified,winner,no need to take exam again'
        
        if examscore<60:        
            print('sorry,better luck next time!')
        elif examscore>100:
            print('you are cheating!')
        else:
            self.__score+=examscore
            self.times+=1
            print('OK!')
            if self.times==8 and self.__score/self.times>80:#如果參加了八次考試,且平均分數大於80分,即可畢業
                Student.student_graduated+=1
                Student.student_graduated_name_list.append(self.name)
                
            
    
    def check(self,):
        if self.times<8:
            return 'you need to do more {8-self.times} tests to graduate!'
        elif self.__score/self.times<80:
            return 'sorry,you are not qualified in ss,your mean score is {self.__score/self.times}'            
        else:
            return 'you alreay graduated,winner!'
        
    @classmethod
    def get_graducated_student(cls,):
        return cls.student_graduated
    
    @classmethod
    def get_graducated_student_list(cls,):
        return cls.student_graduated_name_list
    

類實例化對象並使用

#實例化並使用上面創建的類,並使用
ss=Student("zhangsan",18,"男")
ss.exam(70)
ss.check()

類成員一覽

  • 數據成員
    • 類變量與實例變量
  • 方法成員
    • 類方法與實例方法
擴展閱讀:私有成員
#私有成員:對類內部的屬性及方法,通過在在標識符前加雙 下劃線__來實現的私有化
#即使是在成員名面前加了__,依舊可以訪問到。
 #因爲python使用一種 name mangling 技術,將 __membername替換成 _classname__membername
ss._Student__score

輸出結果爲:

70

類中的關鍵字與裝飾器詳解

類中的關鍵字

#關鍵字
# cls
# cls是指向類的指針,在類方法中第一個形參要命名爲cls.

# self
# self是指向每個獨立對象的指針.在實例方法中第一個形參被命名爲self,以區別其它函數。 
#對象方法以self參數,類方法以cls參數來傳遞。

類中的裝飾器

#這個的作用就是讓全部結果都顯示出來。
%config ZMQInteractiveShell.ast_node_interactivity='all'
#裝飾器
#@staticmethod:類靜態方法
#@classmethod:類方法


#@property—把函數調用僞裝成對屬性的訪問,數據描述符屬性的優先級高於實例名稱空間中的同名成員。
# 使用@property,不用再像java中使用getter,setter方法去設置和訪問類變量   
# 這時,也只有通過@property,才能對實例變量進行訪問或設置,實現了對變量訪問的控制,

class Student1():
    def __init__(self,name,age):  ###__init__實例初始化
        self.name = name       ####self:實例變量,變量的名字叫name
        self.__age=age
        
    @property #getter
    def name1(self):
        return self.name
    
    @name1.setter  # setter
    def name1(self,newname):
        self.name = newname
        
    @property #getter
    def age(self):
        return self.__age
    
    @age.setter  # setter
    def age(self,newage):
        self.__age = newage
        
# 上面這樣設置的是類變量可以被類實例隨意訪問,修改。
# 注意,這裏的name1,如果和實例變量name重名會導致,無限遞歸!!!
# RecursionError: maximum recursion depth exceeded while calling a Python object

# 但如果想讓@property和類實例變量同名呢?  
# 將實例變量設置爲私有(像age一樣)就不會導致重名引發遞歸死機了
s1=Student1('jack',33)
s1.name1
s1.name1="zhangsan"
s1.name1

s1.age#getter
s1.age=22#setter
s1.age

輸出結果爲:

'jack'
'zhangsan'
33
22
擴展閱讀 魔術方法,__*__
  • 魔法方法就是可以給你的類增加魔力的特殊方法,如果你的對象實現(重載)了這些方法中的某一個,那麼這個方法就會在特殊的情況下被 Python 所調用,
  • 你可以定義自己想要的行爲,這些會自動發生。
  • 它們經常是兩個下劃線包圍來命名的

練習題:

完成公司類的設計

  • 設計以下公司類,並實例化不同對象進行檢查
  • 類成員
    • 類下公司的總個數
  • 類方法
    • 返回公司類共有多少個公司實例
  • 實例變量
    • 公司名,簡介,利潤,銷售額,總成本,僱員姓名,僱員人員。
  • 實例方法要求有:
    • 招聘人才(每招一個人會有成本產生,影響僱員列表,人數,總成本)
    • 解僱人員(每解僱一個人會有成本產生,影響僱員列表,人數 ,總成本)
    • 公司廣告推廣 ( 影響總成本 )
    • 交社保 ( 按公司僱員總人數計算,影響總成本 )
    • 交稅 ( 按公司僱員總人數計算,影響總成本 )
    • 銷售(按銷售件數 * 價格計算銷售額,利潤按銷售額 * 利潤率進行計算利潤。)
    • 獲取公司僱員列表
    • 獲取公司淨利潤
class Company():
    company_list=[]
    
    def __init__(self,name,intro,totalcost,employees):
        self.name=name
        self.intro=intro
        self.profit=0
        self.sales=0
        self.totalcost=totalcost
        self.employees=employees
        Company.company_list.append(name)
        
    @classmethod
    def get_company_list(cls,):
        return cls.company_list
    
    def recruit(self,newemployee,cost):
        self.employees.append(newemployee)
        self.totalcost-=cost
    
    def fire(self,employeename):
        self.employees.remove(employeename)
        
    def advertising(self,cost):
        self.totalcost-=cost
        
    def social_insurance(self):
        self.totalcost-=len(self.employees)*120
    
    def pay_tax(self):
        self.totalcost-=len(self.employees)*12
        
    def sale(self,price,totalcount):
        sales=price*totalcount
        self.sales+=sales
        self.profit+=sales*0.03
    
    def get_employees(self):
        return self.employees
    
    def get_profit(self):
        return self.profit
    
    def get_totalcost(self):
        return self.totalcost
    

employees=['張三1','張三2','張三3','張三4']    
cc=Company('百度','介紹百度公司',10000,employees)
cc2=Company('阿里','介紹阿里公司',20000,employees)
Company.get_company_list()
cc.recruit('李四',100)
cc.fire('張三1')
cc.advertising(3000)
cc.social_insurance()
cc.pay_tax()
cc.sale(100,1000)
cc.get_employees()
cc.get_profit()
cc.get_totalcost()
        
        

輸出結果爲:

['百度', '阿里']
['張三2', '張三3', '張三4', '李四']
3000.0
6372
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章