1. 程式人生 > >python自動化_day6_面向對象_組合,繼承,多態

python自動化_day6_面向對象_組合,繼承,多態

基本 只需要 self. pytho super() width 搜索路徑 顯示 發生

復習:http://www.cnblogs.com/Eva-J/articles/7228075.html

模塊

 1 import collections,os,sys,re,random,time
 2 collections.defaultdict()  #默認字典   默認字典的優勢就是該字典中如果沒有元素就直接添加
 3 collections.OrderedDict()  #有序字典   字典是有序的可以直接用索引調用
 4 collections.namedtuple()   #可命名元祖 可以把兩個元組重命名之後簡單調用
 5 time.time()  #時間戳時間
 6 time.strftime()#
字符串時間 7 time.localtime()#結構化時間 8 random.choice([1,23,[4,5]]) # #1或者23或者[4,5] #隨機選擇一個返回 9 random.randint(1,5)# 大於等於1且小於等於5之間的整數 10 random.randrange(1,10,2) # 大於等於1且小於10之間的奇數 11 random.sample([1,23,[4,5]],2) # #列表元素任意2個組合 12 #os模塊中很多跟操作系統相關的東西 13 #文件相關 14 #文件夾相關的 15 #和執行系統命令相關 16 #
和路徑相關的 17 sys.argv() #命令行參數List,第一個元素是程序本身路徑 18 sys.exit() #退出程序,正常退出時exit(0),錯誤退出sys.exit(1) 19 sys.version #獲取Python解釋程序的版本信息 20 sys.path #返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值 21 sys.platform #返回操作系統平臺名稱 22 #re模塊中的正則表達式使用很重要

初識面向對象

模擬一個人狗大戰的遊戲:使用函數,來寫人狗大戰

 1 #首先進一個遊戲公司
2 #寫人狗大戰的遊戲 3 #想一下 需要有一個人 一個狗 需要互相攻擊(動作)會影響遊戲人物或者狗的值的變化 4 #人 需要有基礎屬性(生命值,武力值,名字,性別,背包) 5 def Person(name,sex,hp,dps): #人模子 創建出來的所有人都有相同的屬性值 6 dic = {name:name,sex:sex,hp:hp,dps:dps,bag:[]} 7 return dic 8 alex = Person(alex,N,250,5) 9 #狗 需要有基礎屬性(生命值,武力值,名字,品種) 10 def Dog(name,kind,hp,dps): 11 dic = {name: name, kind: kind, hp: hp, dps: dps} 12 return dic 13 ha2 = Dog(哈士奇,藏獒,15000,200) 14 #需要給人和狗安排技能 人可以打狗,狗可以咬人 15 print(alex) 16 print(ha2) 17 #人打狗 18 def attack(person_name,dog_name,person_dps,dog_hp): 19 print(%s打了%s,%s掉了%s點血,還剩%s血 %(person_name,dog_name,dog_name,person_dps,dog_hp-person_dps)) 20 attack(alex[name],ha2[name],alex[dps],ha2[hp]) 21 print(ha2) 22 #目前問題 人大狗只是顯示了一個數值沒有改變原狗的屬性,並且傳參還特別麻煩所以需要想辦法 23 def attack(person,dog): 24 dog[hp] -= person[dps] 25 print(%s打了%s,%s掉了%s點血,還剩%s血 %(person[name],dog[name],dog[name],person[dps],dog[hp])) 26 attack(alex,ha2) 27 #狗咬人 28 def bite(dog,person): 29 person[hp]-= dog[dps] 30 print(%s咬%s,%s掉了%s點血,還剩%s血 % (dog[name], person[name], person[name], dog[dps], person[hp])) 31 bite(ha2,alex) 32 print(ha2,alex) 33 #從這裏基本實現了人打狗,狗咬人的互動 但是有一個問題,思考如果人咬狗或者狗打人會怎麽辦,這是一個問題所以我們需要進行動作限制

下面思考需要對動作做限制可以如下:

 1 def Person(name,sex,hp,dps):
 2     dic = {name:name,sex:sex,hp:hp,dps:dps,bag:[]}
 3     def attack(dog):
 4         dog[hp] -= dic[dps]
 5         print(%s打了%s,%s掉了%s點血,還剩%s血 % (dic[name], dog[name], dog[name], dic[dps], dog[hp]))
 6     dic[attack] = attack
 7     return dic
 8 def Dog(name,kind,hp,dps):
 9     dic = {name: name, kind: kind, hp: hp, dps: dps}
10     def bite(person):
11         person[hp] -= dic[dps]
12         print(%s咬%s,%s掉了%s點血,還剩%s血 % (dic[name], person[name], person[name], dic[dps], person[hp]))
13     dic[bite] = bite
14     return dic
15 alex = Person(alex,N,250,5)
16 ha2 = Dog(哈士奇,藏獒,15000,200)
17 
18 print(alex)
19 print(ha2)
20 print(alex[attack])
21 alex[attack](ha2)

以上就是使用了基本的面向對象的思想。

面向過程的程序設計的核心是過程(流水線式思維),過程即解決問題的步驟,面向過程的設計就好比精心設計好一條流水線,考慮周全什麽時候處理什麽東西。

優點是:極大的降低了寫程序的復雜度,只需要順著要執行的步驟,堆疊代碼即可。

缺點是:一套流水線或者流程就是用來解決一個問題,代碼牽一發而動全身。

應用場景:一旦完成基本很少改變的場景,著名的例子有Linux內核,git,以及Apache HTTP Server等。

面向對象的程序設計的核心是對象(上帝式思維),要理解對象為何物,必須把自己當成上帝,上帝眼裏世間存在的萬物皆為對象,不存在的也可以創造出來。面向對象的程序設計好比如來設計西遊記,如來要解決的問題是把經書傳給東土大唐,如來想了想解決這個問題需要四個人:唐僧,沙和尚,豬八戒,孫悟空,每個人都有各自的特征和技能(這就是對象的概念,特征和技能分別對應對象的屬性和方法),然而這並不好玩,於是如來又安排了一群妖魔鬼怪,為了防止師徒四人在取經路上被搞死,又安排了一群神仙保駕護航,這些都是對象。然後取經開始,師徒四人與妖魔鬼怪神仙互相纏鬥著直到最後取得真經。如來根本不會管師徒四人按照什麽流程去取。

面向對象的程序設計的

優點是:解決了程序的擴展性。對某一個對象單獨修改,會立刻反映到整個體系中,如對遊戲中一個人物參數的特征和技能修改都很容易。

缺點:可控性差,無法向面向過程的程序設計流水線式的可以很精準的預測問題的處理流程與結果,面向對象的程序一旦開始就由對象之間的交互解決問題即便是上帝也無法預測最終結果。於是我們經常看到一個遊戲人某一參數的修改極有可能導致陰霸的技能出現,一刀砍死3個人,這個遊戲就失去平衡。

應用場景:需求經常變化的軟件,一般需求的變化都集中在用戶層,互聯網應用,企業內部軟件,遊戲等都是面向對象的程序設計大顯身手的好地方。

在python 中面向對象的程序設計並不是全部。

面向對象編程可以使程序的維護和擴展變得更簡單,並且可以大大提高程序開發效率 ,另外,基於面向對象的程序可以使它人更加容易理解你的代碼邏輯,從而使團隊開發變得更從容。

了解一些名詞:類、對象、實例、實例化

類:具有相同特征的一類事物(人、狗、老虎)

對象/實例:具體的某一個事物(隔壁阿花、樓下旺財)

實例化:類——>對象的過程(這在生活中表現的不明顯,我們在後面再慢慢解釋)

按照以前的邏輯,人狗大戰創建一個人,創建一只狗,人打狗,狗咬人,兩個函數做一些動作,可以理解為面向過程編程

造模子 -------->>>面向對象

好處:規範了一些角色的屬性項目,屬性的名字,技能,技能的名字

權限:有一些函數只能是這個角色才可以調用

面向對象的規則:類被創造出來 就是一個模子,誰為了描述對象的

  類:具有相同屬性和相同動作的一類事物組成一個類 類是抽象的

  對象:具體的某一個具有實際屬性和具體動作的一個實體,對象是具體的

只要是寫在類名字中的名字,不管是變量還是函數名,都不能在類的外邊直接使用
類的功能:查看屬性、實例化----創建對象

 1 class 類名:
 2     靜態屬性 = 123
 3     def 動態屬性(self):  #self  在類中的方法一個默認的參數
 4         print(self)
 5 print(類名.靜態屬性)
 6 類名.靜態屬性 = 456
 7 print(類名.靜態屬性)
 8 類名.靜態屬性2 = abc
 9 print(類名.靜態屬性2)
10 del 類名.靜態屬性2
11 print(類名.靜態屬性2)
12 print(類名.__dict__)  #類中必要的默認值之外,還記錄了程序員在類中定義的所有名字

類名可以查看某個方法,但是一般情況下,我們不直接使用類名調用方法,類的函數名第一個字母一定是大寫的,函數的第一個字母一定是小寫的。

創建一個類:

 1 class Person:pass
 2 alex = Person()
 3 print(alex)  #object  對象  alex是Person類的一個對象
 4 對象  = 類名()
 5 print(Person)
 6 print(alex.__dict__)
 7 # alex name hp  dps bag sex
 8 alex.__dict__[name] = alex
 9 alex.__dict__[sex] = N
10 alex.__dict__[hp] = 250
11 alex.__dict__[dps] = 5
12 alex.__dict__[bag] = []
13 print(alex.__dict__)
14 alex.name = alex
15 alex.hp = 250
16 alex.dps = 5
17 alex.bag = []
18 alex.sex = N
19 print(alex.__dict__)

分析:為什麽會執行init中的內容 self到底是什麽

實例化的過程:

  1、類名()就是實例化

  2、在實例化的過程中發生了很多事情外部是看不到的

  3、創造一個對象,自動調用__init__方法

  4、這個被創造的對象會被當做實際參數傳到__init__方法中,並且傳給第一個self參數

  5、執行__init__方法中的內容

  6、自動把self方法作為返回值,返回給實例化的地方

 1 #人狗大戰 使用面向對象
 2 class Person:
 3     def __init__(self,name,hp,sex,dps):
 4         self.name = name
 5         self.hp = hp
 6         self.sex = sex
 7         self.dps = dps
 8         self.bag = []
 9     def attack(self,dog):
10         dog.hp -= self.dps
11         print(%s打了%s,%s掉了%s點血,還剩%s血 % (self.name, dog.name, dog.name, self.dps, dog.hp))
12 class Dog:
13     def __init__(self,name,hp,kind,dps):
14         self.name = name
15         self.hp = hp
16         self.kind = kind
17         self.dps = dps
18     def bite(self,person):
19         person.hp -= self.dps
20         print(%s咬%s,%s掉了%s點血,還剩%s血 % (self.name, person.name, person.name, self.dps, person.hp))
21 alex = Person(aelx,250,N,5)
22 ha2 = Dog(哈士奇,15000,藏獒,200)
23 print(alex.__dict__)  #init的儲存的內容查看使用__dict__
24 Person.attack(alex)  #類中的函數調用
25 alex.attack(ha2)
26 ha2.bite(alex)
27 print(alex.__dict__)
28 print(ha2.__dict__)

對象名 方法名 相當於調用一個函數,這個函數默認把對象名作為第一個參數傳入函數中

剩余的其他參數根據我們的需求可以隨意傳

 1 #小練習 計算圓形的面積和周長 已知半徑
 2 from math import pi
 3 class Circle:
 4     def __init__(self,r):
 5         self.r = r
 6     def perimeter(self):
 7         print(2*pi*self.r)
 8     def area(self):
 9         print(pi*self.r*self.r)
10 circle = Circle(5)
11 circle.perimeter()
12 circle.area()
13 
14 #每一個角色都有屬於自己的屬性和方法
15 #高可擴展性  可讀性 規範性
16 #結局不可控

技術分享圖片

#############命名空間####################

類有自己的命名空間,對象也有自己的命名空間,分析對象是否可以訪問類的命名空間,類是否可以訪問對象的命名空間

1 class Person:
2     COUNTRY = 中國人  #靜態屬性
3     def __init__(self,name):
4         self.name = name
5     def eat(self):
6         print(%s在吃泔水 %self.name)
7 alex = Person(alex)
8 egon = Person(egon)
#當一個類在創建一個實例的時候,就產生了一個這個實例和類之間的聯系
#可以通過實例 對象 找到實例化它的類
#類不能找到他的實例化
#在訪問變量的時候,都先使用自己命名空間中的,如果自己的空間沒有,再到類的空間中去找
#在使用對象修改靜態變量的過程中,相當於在自己的空間中創建了一個新的變量
#在類的靜態變量的操作中,應該使用類名來直接進行操作,就不會出現烏龍操作

技術分享圖片

1 #創建一個類,計算這個類創建了多少個實例
2 class Foo:
3     count = 0
4     def __init__(self):
5         Foo.count += 1
6 f1 = Foo()
7 print(Foo.count)

###########################組合#########################

 1 組合: 一個類的對象作為另外一個類對象的的屬性
 2 class Person:
 3     def __init__(self,name,hp,sex,dps):
 4         self.name = name
 5         self.hp = hp
 6         self.sex = sex
 7         self.dps = dps
 8         self.bag = []
 9     def attack(self,dog):
10         dog.hp -= self.dps
11         print(%s打了%s,%s掉了%s點血,還剩%s血 % (self.name, dog.name, dog.name, self.dps, dog.hp))
12 class Dog:
13     def __init__(self,name,hp,kind,dps):
14         self.name = name
15         self.hp = hp
16         self.kind = kind
17         self.dps = dps
18     def bite(self,person):
19         person.hp -= self.dps
20         print(%s咬%s,%s掉了%s點血,還剩%s血 % (self.name, person.name, person.name, self.dps, person.hp))
21 alex = Person(aelx,250,N,5)
22 ha2 = Dog(哈士奇,15000,藏獒,200)
23 print(alex.name)
 1 #基礎數據類型 都是類
 2 #‘alex‘ : str 的對象
 3 # alex.name = ‘alex‘
 4 #給alex裝備一個武器  alex打不過狗花錢裝備一個武器
 5 class  Weapon:
 6     def __init__(self,name,price,dps):
 7         self.name = name
 8         self.price = price
 9         self.dps = dps
10     def kill(self,dog):
11         dog.hp -= self.dps
12 dagoubang = Weapon(dagougun,600000,10000)
13 alex.money = 1000000
14 if alex.money >= dagoubang.price:
15     alex.weapon = dagoubang
16     alex.weapon.kill(ha2)
17     print(ha2.hp)

計算圓環的面積和周長,已知外圓

 1 from math import pi
 2 class Circle:
 3     def __init__(self,r):
 4         self.r = r
 5     def perimeter(self):
 6         return 2*pi*self.r
 7     def area(self):
 8         return pi*self.r*self.r
 9 # circle = Circle(5)
10 class Cirque:
11     def __init__(self,outside_r,inside_r):  #已知外圓內園的半徑調用外圓的方法就是直接調用外圓類的函數
12         self.out_circle = Circle(outside_r)
13         self.in_circle = Circle(inside_r)
14     def perimeter(self):
15         return self.out_circle.perimeter() + self.in_circle.perimeter()
16     def area(self):
17         #返回大圓面積 - 小圓面積
18         return  self.out_circle.area() - self.in_circle.area()
19 ring = Cirque(10,5)
20 print(ring.area())
21 print(ring.perimeter())
#組合是描述了一種什麽有什麽的關系  圓環有圓   人有武器
#面向對象初識
# 如何創建一個類
# 類的實例化 # 實例和對象是一回事
# 對象調用方法
# 類調用靜態屬性
# __init__
#命名空間
#類的組合用法  人有武器 圓環有圓  兩個類之間有關系 調用類的方法或者函數

#####################繼承###########################

#為什麽會有繼承  為了解決代碼的冗余問題
class Person:
    def __init__(self,name,hp,sex,dps):
        self.name = name
        self.hp = hp
        self.sex = sex
        self.dps = dps
        self.bag = []
    def attack(self,dog):
        dog.hp -= self.dps
        print(%s打了%s,%s掉了%s點血,還剩%s血 % (self.name, dog.name, dog.name, self.dps, dog.hp))
class Dog:
    def __init__(self,name,hp,kind,dps):
        self.name = name
        self.hp = hp
        self.kind = kind
        self.dps = dps
    def bite(self,person):
        person.hp -= self.dps
        print(%s咬%s,%s掉了%s點血,還剩%s血 % (self.name, person.name, person.name, self.dps, person.hp))
alex = Person(aelx,250,N,5)
ha2 = Dog(哈士奇,15000,藏獒,200)
print(alex.name)
#分析以上代碼人和狗都有相同的屬性,如果單獨寫,會顯得很啰嗦,為了解決這個辦法可以使用面向對象的繼承

繼承分為:單繼承和多繼承

 1 #單繼承
 2 class Parent:pass
 3 class Son(Parent):pass
 4 #Son 類繼承Parent類
 5 #父類  基類 超類 ------Parent類
 6 #子類 派生類 -------Son類
 7 
 8 #多繼承
 9 class Parent1:pass
10 class Parent2:pass
11 class Son(Parent1,Parent2):pass

解決上面人狗大戰中代碼冗余問題:直接使用繼承,創建一個動物類,包含人和狗一些必要的屬性。

 1 class Animal:
 2     def __init__(self,name,hp,dps):
 3         print(---------->)
 4         self.name = name
 5         self.hp = hp
 6         self.dps = dps
 7     def eat(self):   #父類的eat方法子類可以調用
 8         print(%s吃藥回血了 %self.name)
 9 class Person(Animal):
10     def __init__(self,name,hp,dps,sex):
11         super().__init__(name,hp,dps)# Animal.__init__(self,name,hp,dps)
12         self.sex = sex
13     def attack(self, dog):
14         dog.hp -= self.dps
15         print(%s打了%s,%s掉了%s點血,還剩%s血 % (self.name, dog.name, dog.name, self.dps, dog.hp))
16 
17 class Dog(Animal):
18     def __init__(self,name, hp, dps,kind):
19         super().__init__(name, hp, dps)# Animal.__init__(self, name, hp, dps)
20         self.kind = kind
21     def bite(self, person):
22         person.hp -= self.dps
23         print(%s咬%s,%s掉了%s點血,還剩%s血 % (self.name, person.name, person.name, self.dps, person.hp))
24 alex = Person(alex,250,5,N)
25 ha2 = Dog(哈士奇,15000,200,藏獒)
26 print(alex.__dict__)
27 print(ha2.__dict__)
28 ha2.eat()
29 alex.eat()
30 ha2.bite(alex)
31 alex.attack(ha2)
 1 #面試題
 2 class Foo:
 3     def __init__(self):
 4         self.func()
 5     def func(self):
 6         print(in foo)
 7 class Son(Foo):
 8     def func(self):
 9         print(in son)
10 Son()
11 
12 #python兩種類
13     #python3已經滅絕了 經典類
14         #經典類都遵循深度優先算法
15     #新式類 python3所有的類都是新式類      class A(object): 所有的新式類都繼承object
16         #新式類在多繼承中都遵循廣度優先算法
17 #super和找父類這件事是兩回事
18 #在單繼承中super就是找父類
19 #在多級繼承中 super的軌跡 是根據整個模型的起始點展開一個廣度優先算法 遵循mro規則來的

python自動化_day6_面向對象_組合,繼承,多態