面向對象
分類
- 面像過程編程:初學者容易接受,從上往下依次執行。
- 面向函數編程:將某功能的代碼封裝爲一個函數,使用時僅調用函數。
- 面向對象編程:對函數進行分類和封裝
class people: # 經典類
class People(object): # 新式類,object類是所有類的基類/父類
def __init__(self,name,age): # 構造函數,當實例化對象時自動調用,self是實例化出來的對象
self.name = name # 屬性
self.age = age
def run(self): # 方法
print "running...."
def __del__(self):
print "deleteing......" # 析構函數,刪除實例化對象時自動調用;
class Student(People): # Student是子類,繼承People這個父類;
pass
p1 = People("張策",18)
p1.run()
什麼是面向對象?
類 ===== 建房子的圖紙 (三室一廳,兩室一廳…….)
對象===== 實際建出來的房子(門牌號)
class ThreeRoom:
pass
seven_zero_one = ThreeRoom()
seven_zero_one.live()
seven_zero_one.clean()
面向對象的三個特性:
封裝
- 封裝:把內容統一放在一個地方,看成一個整體,(實例化對象self和類的屬性綁定在一起);
- 訪問封裝內容的兩種方式:
通過self去訪問封裝的內容;(self.name)
通過實例化的對象名去訪問封裝的內容;(p1 = People(“westos”,17) p1.age)
繼承(子承父業)
- 新名詞:基類/派生類, 父類/子類, 新式類和經典類
- 多繼承:
新式類: 廣度優先繼承;(python2.x和python3.x均支持)
經典類:深度優先繼承;(python2.x支持,python3.x沒有經典類) - 注意: 類的方法中可以傳遞一個對象;
class People(object): # 新式類,object類是所有類的基類/父類
def __init__(self,name,age): # 構造函數,當實例化對象時自動調用;
self.name = name # 屬性
self.age = age
print "%s is create...." %(self.name)
def run(self): # 方法
print "%s running...." %(self.name)
def __del__(self):
print "deleteing......" # 析構函數,刪除實例化對象時自動調用;
class Relation(object):
**def make_relation(self,obj):** #傳入一個對象作爲參數
print "%s is related with %s" %(self.name,obj.name)
class Student(People,Relation): # Student是子類,繼承People這個父類;
def __init__(self,name, age, sid):
# People.__init__(self,name,age) # 如果父類名更改,此處也需要更改;
super(Student, self).__init__(name,age) # 更推薦使用
self.sid = sid
class Teacher(People,Relation):
def __init__(self, name, age, tid):
#People.__init__(self,name,age)
super(Teacher, self).__init__(name, age)
self.tid = tid
s1 = Student("lijian", 18, "007")
t1 = Teacher("westos", 18, "001")
s1.make_relation(t1)
多態
- 類的屬性
在內存中只需要存儲一次
在構造函數中的屬性,每實例化一個就要存儲一次
class People(object):
def __init__(self,name,country="China"):
self.name = name
self.country = country
p1 = People("飛天")
print p1.name
p2 = People("lala")
print p2.name
#結果爲:
飛天
lala
- 多態
如果子類調用的方法,子類沒有,父類有,運行父類;
如果子類調用的方法,子類有,父類也有,只運行子類的;
面向對象進階
- 類變量,全局變量在內存中只存儲一份
- 普通的對象屬性,每個對象中都要存儲一份
class People(object):
# def __init__(self,name,age,country="china"): #每創建一個實例就會在內存中重新存儲一次
# self.name=name
# self.age=age
# self.country=country
country="China" #全局變量,類的屬性,只需要存儲一次
def __init__(self,name,age):
self.name=name
self.age=age
def run(self):
print "%s is running..."%self.name
p1=People("mj",18)
print p1.name ,p1.age,p1.country
print id(People.country),id(p1.country)
特殊屬性
裝飾器property
他就是裝飾函數的一個函數
#該方法實現了裝飾器的功能,但是調用函數的方式發生了改變。
import time
def dtimer(fun):
def timer(*args,**kwargs): # 高階函數 #args = (1,2,3,4)
start_time = time.time()
fun(*args,**kwargs) # args =(1,2,3,4), 解包*(1,2,3,4)
stop_time = time.time()
return "run %s" % (stop_time - start_time)
return timer # 返回的是timer的地址,要執行該函數需要timer()
@dtimer # fun1 = dtimer(fun1)
def fun1(*args,**kwargs):
print "in the fun1....."
print args
time.sleep(1)
def fun2():
print "in the fun2....."
time.sleep(0.5)
print fun1(1,2,3,4)
# print timer(fun2)
#類中的幾種方法
class Date(object):
def __init__(self,year, month,day):
self.year = year
self.month = month
self.day = day
def echo_date(self):
print "Year:",self.year
print "Month:",self.month
print "Day:",self.day
@classmethod
def from_str(cls,s): # class,類方法的第一個參數是類本身,cls = Date
year, month, day = map(int, s.split("-"))
d = cls(year,month,day) # d = Date(year,month,day)
return d # 對象
@staticmethod
def is_date_legal(s): # 靜態方法,第一個參數既不是對象,也不是類本身,
year, month, day = map(int, s.split("-"))
return year >= 1970 and 0 < month <= 12 and 0 < day <= 31
#d = Date(2017,9,9)
#d.echo_date()
#d1 = Date.from_str('2018-10-19')
#d1.echo_date()
print "legal" if Date.is_date_legal('2017-13-16') else "illegal"
匿名函數
- lambda 形參 : 返回值
#這裏的形參,可以賦默認值,形參和返回值都可以使用*args和**kwargs。
f = lambda x,y:x-y
print f (1,2)
#返回結果爲1