1. 程式人生 > >python 第六天

python 第六天

面向物件介紹:

1、面向物件有兩大特性:

1.1、class:

一個類即是對一類擁有相同屬性的物件的抽象、藍圖、原型。在類中定義了這些物件的都具備的屬性(variables(data))、共同的方法

1.2、object:

一個物件即是一個類的例項化後例項,一個類必須經過例項化後方可在程式中呼叫,一個類可以例項化多個物件,每個物件亦可以有不同的屬性,就像人類是指所有人,每個人是指具體的物件,人與人之前有共性,亦有不同

class Dog(object):
def __init__(self,name): #建構函式,在例項化時做一些類的初始化工作,self是每次例項化d1或者d2那個記憶體空間,就是例項本身
self.name = name #例項變數(靜態屬性)
def bulk(self): #類的方法,功能(動態屬性),這裡的self也是表示例項化的本身,因為要呼叫相關的記憶體空間
print("%s wang wang wang!" %self.name)

#d1 = Dog("test1")
此時self相當於d1,Dog(d1,"test1")
d1 = Dog("test1") #Dog類的例項,代表吧d1.test1傳給了Dog類,這樣子self就是d1本身
d2 = Dog("test2") #生成一個例項,會自動把引數穿個Dog下的__init__(.....)

d1.bulk() #只有經過例項化後,才能呼叫類中的方法
d2.bulk()

2、類的3大特性

2.1、封裝

在類中對資料的賦值、內部呼叫對外部使用者是透明的,這使類變成了一個膠囊或容器,裡面包含著類的資料和方法

其實就是使用構造方法將內容封裝到某個具體物件中,然後通過物件直接或者self間接獲取被封裝的內容

2.2、繼承

一個類可以派生出子類,在這個父類裡定義的屬性、方法自動被子類繼承

class People(object):  
def __init__(self,name,age):
self.name = name
self.age = age

def eat(self):
print("%s is eating.." %self.name)

def talk(self):
print("%s is talking..." %self.name)

def sleep(self):
print("%s is sleeping.." %self.name)

class Relation(object):
def make_friends(self,obj):
print("%s is making friends with %s " %(self.name,obj.name))
class Man(People,Relation):
  def __init__(self,name,age,money):
    super(Man,self).__init__(name,age) #廣式繼承父類的相關屬性,不用自己再聲明瞭,父類已經宣告好了
    self.money = money #父類中沒有的屬性,再進行宣告
    print("%s 一出生就有 %s" %(self.name,self.money))
  def piao(self):
    print("%s is piaoing ..... 20s... done" %self.name)
  def sleep(self): #如果這裡有的話,就不會執行父類的方法,這叫重構父類方法
    People.sleep(self) #先繼承了父類的方法
    print("man is sleeping")

class Woman(People): #Woman類完全繼承了People中的靜態屬性,沒有對靜態屬性進行重構
  def get_birth(self): #新加了方法
    print(“%s is born a baby” %self.name)

m1 = Man("test1",'18',100000) #必須傳入三個引數
m1.eat() #其實呼叫了父類的中方法
m1.sleep() #呼叫的是自己中的方法,只不過繼承了父類的方法
w1 = Woman("test2","20")
m1.make_friends(w1) #因為上邊的m1繼承了Relation
類,make_friends中又傳入兩個引數,一個是類本身和另一個類
這句話的意思是 make_friends(m1,w1) 這樣子就不難理解每次寫self意義了,還有就是每次例項化為什麼寫 m1 = Man()

2.3、多型
簡單的說就是一種方法,多種形態,多型的目標是實現一個介面的重複利用
class Animal(object):
def __init__(self, name): # Constructor of the class
self.name = name

def talk(self): # Abstract method, defined by convention only
raise NotImplementedError("Subclass must implement abstract method")

@staticmethod #靜態函式就是和類沒有直接關聯的,所以animal_talk(self)沒用
def animal_talk(obj):
obj.talk()

class Cat(Animal):
def talk(self):
print('%s: 喵喵喵!' % self.name)


class Dog(Animal):
def talk(self):
print('%s: 汪!汪!汪!' % self.name)


# def func(obj): # 一個介面,多種形態
# obj.talk()


c1 = Cat('小晴')
c1.talk() #標準情況下,可以呼叫類下自己的方法,所以方法裡沒有任何引數
d1 = Dog('李磊')

Animal.animal_talk(c1) #靜態方法中,因為和類沒有直接關係,所以可以傳入自己定義的引數
Animal.animal_talk(d1)
3、類的特殊方法:
3.1、靜態方法,就是類不能直接呼叫了自己的函數了,和類沒有直接關係了,需要傳入相應的引數,上邊例子已經有了。
3.2、類方法:類方法只能訪問類變數,不能訪問例項變數
class Dog(object):
n = “yun”
def __init__(self,name):
self.name = name

@classmethod
def eat(self):
print("%s is eating %s" %(self.n,'flood'))


d = Dog("Test")
d.eat() #d.eat()中執行的結果是:yun is eating flood,而不是Test is eating flood,因為此方法調用不了例項的引數,只能調類中的yun
3.3、屬性方法:
將類中的方法變為類的屬性,呼叫的時候,只能用f.flight_status 而不能用 f.flight_status()
class Flight(object):
def __init__(self,name):
self.flight_name = name


def checking_status(self):
print("checking flight %s status " % self.flight_name)
return 1


@property #將方法變為屬性
def flight_status(self):
status = self.checking_status() #在這裡進行呼叫了方法
if status == 0 :
print("flight got canceled...")
elif status == 1 :
print("flight is arrived...")
elif status == 2:
print("flight has departured already...")
else:
print("cannot confirm the flight status...,please check later")

f = Flight("747")
f.flight_status
此時遇到有一個問題,不能對類的屬性進行賦值,比如你想f.flight_status = 2,是不允許進行直接賦值的,如果想直接賦值,需要加裝飾器:
@flight_status.setter @flight_status.deleter
如下:
    @flight_status.setter #修改
def flight_status(self,status):
status_dic = {
0 : "canceled",
1 :"arrived",
2 : "departured"
}
print("\033[31;1mHas changed the flight status to \033[0m", status_dic[status])
#又get到新的技能,字典可以用get方法,status_dic.get() status_dic.get(status)

@flight_status.deleter #刪除
def flight_status(self):
print("status got removed...")

f = Flight("CF747")
f.flight_status
f.flight_status = 2
del f.flight_status
f.flight_status

3.4、反射:通過字串對映或修改程式執行時的狀態、屬性、方法, 有以下4個方法
# #### 檢查是否含有成員 ####
hasattr(obj, 'name') hasattr(obj, 'func')

# #### 獲取成員 ####
getattr(obj, 'name') getattr(obj, 'func')

# #### 設定成員 ####
setattr(obj, 'age', 18) setattr(obj, 'show', lambda num: num + 1)

# #### 刪除成員 ####
delattr(obj, 'name') delattr(obj, 'func')
 
def bulk(self):
print("%s is yelling..." %self.name)
class Dog(object):
def __init__(self,name):
self.name = name

def eat(self,food):
print("%s is eating..."%self.name,food)



d = Dog("NiuHanYang")
choice = input(">>:").strip() #此處



if hasattr(d,choice): #假如有這個屬性
delattr(d,choice) #刪除方法需要輸入eat()
fun = getattr(d,choice) #輸入的是eat,choice就是eat中的food這個引數,這是對方法的處理
fun("2018") #賦值的相當於是eat中的food
attr = getattr(d,choice)
setattr(d,choice,"33") #這是對類中的屬性進行修改
print(d.age)
else:
setattr(d,choice,bulk) #把外部的函式裝到類裡邊,此時bulk會變成choice中輸入的字元,比如輸入talk
d.talk(d)
# setattr(d,choice,22) #動態屬性的新增
# print(getattr(d,choice))

# print(d.name)

4、異常處理
在程式設計過程中為了增加友好性,在程式出現bug時一般不會將錯誤資訊顯示給使用者,而是現實一個提示的頁面。
def bulk(self):
print("%s is yelling..." %self.name)
class Dog(object):
def __init__(self,name):
self.name = name

def eat(self,food):
print("%s is eating..."%self.name,food)



# d = Dog("NiuHanYang")
# choice = input(">>:").strip()
# getattr(d,choice)

data = {}
names = [1,2]

try: #程式正常就正常執行
# names[3]
# data['name']
open("tes.txt")
# a = 1
# print(a)
# except Exception as e:
# print("出錯了",e)
except (KeyError,IndexError) as e: #具體的錯誤型別
print("沒有這個key",e)
except IndexError as e:
print("列表操作錯誤",e)
except Exception as e: #不管是什麼錯誤型別
print("未知錯誤",e)
else: # #主程式碼塊執行完,執行該塊
print("一切正常")
finally: # 無論異常與否,最終執行該塊
print("不管有沒有錯都執行")