Python學習筆記Day06~07 - 類
阿新 • • 發佈:2020-07-04
目錄
- 類
- 1.建構函式:在例項化時做一些類的初始化工作
- 2.解構函式:在例項釋放、銷燬的時候自動執行的,通常用於做一些收尾工作,
- 3.例項變數與類變數,類變數是大家共用的屬性,能節省記憶體開銷
- 4.靜態屬性與動態屬性,分別表示變數和方法
- 5.私有方法,私有屬性,加__,在外部無法呼叫
- 6.封裝
- 7.繼承 作用就是減少程式碼量,子類可以重構父類的方法,可以繼承多個父類
- 8.多型 一種介面,多種形態
- 類方法、靜態方法和屬性方法
- 12.類的特殊成員用法:doc,module,class,dict,call,str,getitem,setitem,delitem
- 13.所有類的資料型別就是type,通過__metaclass__可自定義
類
# 普通類的建立方法 # class Foo(object): # def __init__(self, name): # self.name = name # # # f = Foo("alex") # print(type(f)) # print(type(Foo)) # 類的特殊建立方法 def func(self): print('hello %s' %self.name) def __init__(self,name,age): self.name = name self.age = age Foo = type('Foo', (object,), {'func': func, '__init__':__init__}) # 所有類都是type的例項化 f = Foo("Chrn",22) f.func() print(type(Foo))
1.建構函式:在例項化時做一些類的初始化工作
2.解構函式:在例項釋放、銷燬的時候自動執行的,通常用於做一些收尾工作,
如關閉一些資料庫連線,關閉開啟的臨時檔案
3.例項變數與類變數,類變數是大家共用的屬性,能節省記憶體開銷
4.靜態屬性與動態屬性,分別表示變數和方法
5.私有方法,私有屬性,加__,在外部無法呼叫
6.封裝
7.繼承 作用就是減少程式碼量,子類可以重構父類的方法,可以繼承多個父類
py2 經典類是按深度優先來繼承的,新式類是按廣度優先來繼承的
py3 經典類和新式類都是統一按廣度優先來繼承的
8.多型 一種介面,多種形態
class Animal: def __init__(self, name): # Constructor of the class self.name = name def talk(self): # Abstract method, defined by convention only pass #raise NotImplementedError("Subclass must implement abstract method") @staticmethod def animal_talk(obj): obj.talk() class Cat(Animal): def talk(self): print('Meow!') class Dog(Animal): def talk(self): print('Woof! Woof!') d = Dog("陳榮華") #d.talk() c = Cat("徐良偉") #c.talk() # def animal_talk(obj): # obj.talk() Animal.animal_talk(c) # 通過一個介面,按不同的子類實現不同的效果 Animal.animal_talk(d)
類方法、靜態方法和屬性方法
9.靜態方法@staticmethod:不能訪問類變數和例項變數,就相當於一個普通函式,與類的其他屬性無關
# http://www.cnblogs.com/alex3714/articles/5213184.html
class Dog(object):
# __metaclass__ = MyType #指定該類由誰例項化
# def __new__(cls, *args, **kwargs):
# 類的生成、呼叫、順序依次是:__new__ --> __init__ --> __call__
n = 123 # 類變數,可被例項變數覆蓋
def __init__(self, name):
self.name = name # 例項變數(靜態屬性),作用域是例項本身
# @classmethod # 類方法:只能訪問類變數,不能訪問例項變數
# @staticmethod # 靜態方法:不能訪問類變數和例項變數,就相當於一個普通函式,與類的其他屬性無關
# @property # 屬性方法:呼叫不需要加括號,也不能傳引數
def eat(self): #類的方法(動態屬性)
print('%s is eatting...' % self.name)
def __call__(self, *args, **kwargs):
print('例項物件後面加括號觸發') # 用d()呼叫
def __str__(self):
return "列印例項物件時輸出返回的值" # 用d 呼叫
def __getitem__(self, item):
print('索引獲取,如字典')
# 例項:key_value
# result = obj['k1'] # 自動觸發執行 __getitem__
# obj['k2'] = 'alex' # 自動觸發執行 __setitem__
# del obj['k1'] # 自動觸發執行 __setitem__
def __setitem__(self, key, value):
print('索引設定')
def __delitem__(self, key):
print('索引刪除')
d = Dog('金毛') #例項化
d.bullet_prove = True #新增例項變數
del d.name #刪除例項的變數
d.n = '改變類變數' #相當於新增一個例項變數,原本的類變數並沒有改變
#類的特殊成員方法
d.__doc__ #輸出類的描述資訊
d.__module__ #輸出類所屬模組lib
d.__class__ #輸出類所屬類
d.__dict__ #檢視例項中的所有變數
Dog.__dict__ #檢視類中的所有成員
10.類方法@classmethod:只能訪問類變數,不能訪問例項變數
11.屬性方法@property:把一個方法變成一個靜態屬性,呼叫不需要加括號,也不能傳引數
要給屬性方法傳引數只能使用.setter再寫一個同名方法
介面,對使用者來講,只需要屬性的結果,不需要知道其中的過程
class Flight(object):
def __init__(self,name):
self.flight_name = name
def checking_status(self):
print("checking flight %s status " % self.flight_name)
return 0
@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")
@flight_status.setter
def flight_status(self,status):
print("flight %s has changed status to %s" %(self.flight_name,status))
f = Flight("CA980")
f.flight_status
f.flight_status = 2
12.類的特殊成員用法:doc,module,class,dict,call,str,getitem,setitem,delitem
# hasattr(obj,name_str) , 判斷一個物件obj裡是否有對應的name_str字串的方法
# getattr(obj,name_str), 根據字串去獲取obj物件裡的對應的方法的記憶體地址
# setattr(obj,'y',z), is equivalent to ``obj.y = z''
# delattr(obj,z)
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): # 判斷例項是否有這個方法
getattr(d, choice) # 獲得例項中的方法
else:
setattr(d, choice, bulk) # d.talk = bulk 為例項新增方法
func = getattr(d, choice)
func(d)
13.所有類的資料型別就是type,通過__metaclass__可自定義
類的建立過程
class MyType(type):
def __init__(self, what, bases=None, dict=None): # 建立類時執行的第一階段
print("--MyType init---")
super(MyType, self).__init__(what, bases, dict)
def __call__(self, *args, **kwargs): # 建立例項時執行的第二階段第一步
print("--MyType call---")
obj = self.__new__(self, *args, **kwargs)
obj.data = {"name":111}
self.__init__(obj, *args, **kwargs)
class Foo(object):
__metaclass__ = MyType # 定製類的建立過程,預設type
def __init__(self, name): # 建立例項時執行的第二階段第三步
self.name = name
print("Foo ---init__")
def __new__(cls, *args, **kwargs): # 類自帶,用來建立例項,先於__init__執行,第二階段第二步
print("Foo --new--")
#print(object.__new__(cls))
return object.__new__(cls) # 繼承父類的__new__方法 #cls相當於類的self
# 第一階段:直譯器從上到下執行程式碼建立Foo類,執行MyType的__init__方法
# 第二階段:通過Foo類建立obj物件 __call__,__new__,__init__
obj = Foo("Alex")
print(obj.name)