python學(xué)習(xí)筆記之類class(第六天)
參考文檔:
1、金角大王博客:http://www.rzrgm.cn/alex3714/articles/5188179.html
2、銀角大王博客:http://www.rzrgm.cn/wupeiqi/articles/5017742.html
1、反射之__import__:
我們知道import語句是用來導(dǎo)入外部模塊的,當(dāng)然還有from...import...也可以,但是其實(shí)import實(shí)際上是使用builtin函數(shù)__import__來工作的。
在一些程序中,我們可以動態(tài)地去調(diào)用函數(shù),如果我們知道模塊的名稱(字符串)的時(shí)候,我們可以很方便的使用動態(tài)調(diào)用。
__import__(module_name[, globals[, locals[, fromlist]]]) #可選參數(shù)默認(rèn)為globals(),locals(),[]
__import__('os')
__import__('os',globals(),locals(),['path','pip']) #等價(jià)于from os import path, pip
例: 以字符串的形式導(dǎo)入模塊
mod = __import__('sys')
print(mod.path)
例:以字符串的形式調(diào)用模塊中的函數(shù)
func = getattr(mod,'path')
print(func)
例:從一個(gè)包中導(dǎo)入一個(gè)模塊 ,包名為main,模塊名為mod
aa = __import__('main.mod')
aa = __import__('main', globals={}, locals={}, fromlist=['mod'])
aa = __import__('main',globals(),locals(),['mod'])
m = getattr(aa, 'mod')
print(m.first('kevin'))
n = getattr(m, 'first')
print(type(n))
n('kevin')
注:web框架中根據(jù)不同的URL,來加載不同的模塊,進(jìn)行不同的處理。
2、類與對象:
__init__ 的方法 完成初始化。構(gòu)造函數(shù)
__del__ 的方法 對象銷毀,析構(gòu)函數(shù)
__call__ 調(diào)用方法
所有的實(shí)例方法都擁有一個(gè) self 參數(shù)來傳遞當(dāng)前實(shí)例,類似于 this。
可以使用 __class__ 來訪問類型成員。
還有些內(nèi)置特殊的屬性:
__doc__ #類型幫助信息
__name__ # 類型名稱
__module__ # 類型所在模塊
__bases__ # 類型所繼承的基類
__dict__ # 類型字典,存儲所有類型成員信息。
例:
class peason(object):
'''this is peason class'''
#靜態(tài)字段
aa = 'nihao'
bb = ['a',1,'b',2,'c',3]
cc = {'a':'wangkai','b':'gonghui'}
def __init__(self,name,flag):
self.name = name #動態(tài)字段
self.__flag = flag #私有字段
def __del__(self):
print('i will go')
def __call__(self,caa): #call方法
print('this is call method',caa)
def __priv(self): #私有方法
print('hello,this is privacy method',self.__flag)
def first(self): #動態(tài)方法
print('hello,this is dymamic method',self.name)
self.__priv() #調(diào)用私有方法
return self.__flag #調(diào)用私有字段
@staticmethod #靜態(tài)方法
def foo():
print('this is static method')
@property #屬性
def bar(self):
print(self.name)
self.__priv()
return "this is property"
@property #屬性(只讀)
def flag(self):
return self.__flag
@flag.setter #修改私有字段值
def flag(self,value):
self.__flag = value
print('#################')
print(peason.__doc__,peason.__name__,peason.__module__,peason.__bases__,peason.__dict__)
print('#################')
print(peason.aa,peason.bb,peason.cc) #獲取靜態(tài)字段
print('#################')
print(peason.foo()) #獲取靜態(tài)方法
print('#################')
pp = peason('wang','true') #類實(shí)例化
print(pp.name) #通過對象獲取動態(tài)字段
print('#################')
print(pp.first()) #通過對象獲取動態(tài)方法
print('#################')
print(pp.bar) #通過對象獲取屬性
print('#################')
print(pp._peason__priv()) #特殊調(diào)用方式
print('#################')
print(pp.flag)
pp.flag = 'false' #通過屬性修改私有字段值
print(pp.flag)
pp('aa') #call方法調(diào)用
注:靜態(tài)的可以直接通過類來訪問,而動態(tài)的只能通過調(diào)用對象的方式來訪問;
私有字段和方法能通過方法和屬性調(diào)用;
只讀或只寫的字段,修改需要@flag.setter 和 class peason(object):來實(shí)現(xiàn)
3、繼承:
Python編程中類可以承繼父類屬性,形式為class 類名(父類),子類可以繼承父類的所有方法和屬性,也可以重載父類的成員函數(shù)及屬性,須注意的是子類成員函數(shù)若重載父類(即名字相同),則會使用子類成員函數(shù)
例:
class SchoolMember(object):
members = 0 #初始學(xué)校人數(shù)為0
def __init__(self,name,age):
self.name = name
self.age = age
def tell(self):
pass
def enroll(self):
'''注冊'''
SchoolMember.members +=1
print("\033[32;1mnew member [%s] is enrolled,now there are [%s] members.\033[0m " %(self.name,SchoolMember.members))
def __del__(self):
'''析構(gòu)方法'''
print("\033[31;1mmember [%s] is dead!\033[0m" %self.name)
class Teacher(SchoolMember):
def __init__(self,name,age,course,salary):
super(Teacher,self).__init__(name,age)
self.course = course
self.salary = salary
self.enroll()
def teaching(self):
'''講課方法'''
print("Teacher [%s] is teaching [%s] for class [%s]" %(self.name,self.course,'s12'))
def tell(self):
'''自我介紹方法'''
msg = '''Hi, my name is [%s], works for [%s] as a [%s] teacher !''' %(self.name,'Oldboy', self.course)
print(msg)
class Student(SchoolMember):
def __init__(self, name,age,grade,sid):
super(Student,self).__init__(name,age)
self.grade = grade
self.sid = sid
self.enroll()
def tell(self):
'''自我介紹方法'''
msg = '''Hi, my name is [%s], I'm studying [%s] in [%s]!''' %(self.name, self.grade,'Oldboy')
print(msg)
if __name__ == '__main__':
t1 = Teacher("Alex",22,'Python',20000)
t2 = Teacher("TengLan",29,'Linux',3000)
s1 = Student("Qinghua", 24,"Python S12",1483)
s2 = Student("SanJiang", 26,"Python S12",1484)
t1.teaching()
t2.teaching()
t1.tell()
新式類以object為基類,在python3之后版本原來有經(jīng)典類將不在使用,而且新式類的多類繼承是以廣度代替了經(jīng)典類的深度搜索方式。
例,A、B、C、D四個(gè)類,其中B和C繼承A,D又繼承B和C,即class D(B,C)
繼承的方法:
經(jīng)典類的搜索順序是B,A,C 搜索到第一個(gè)方法結(jié)束
新式類的搜索順序是B,C。
例:經(jīng)典類寫法
class A(object):
def __init__(self):
print('this is class A')
def test(self):
print('this is parent test')
class B(A):
def __init__(self):
print('this is class B')
class C(A):
def __init__(self):
print('this is class C')
def test(self):
print('this is son C test')
class D(B,C):
def __init__(self):
print('this is class D')
R = D()
R.test()
經(jīng)典類寫法結(jié)果為:
this is class D
this is parent test
新式類寫法結(jié)果為:
this is class D
this is son C test
4、抽象類+抽象方法 = 接口 (用于規(guī)范)
由于python 沒有抽象類、接口的概念,所以要實(shí)現(xiàn)這種功能得abc.py 這個(gè)類庫,
抽象基類(或者ABCs)是Python里一個(gè)相同的特性。抽象基類由abc模塊構(gòu)成,包含了一個(gè)叫做ABCMeta的metaclass。這個(gè)metaclass由內(nèi)置的isinstance()和issubclass()特別處理
具體方式如下:
from abc import ABCMeta,abstractmethod
from _pyio import __metaclass__
class headers(object):
__metaclass__ = ABCMeta
def __init__(self):
print('this is abc class')
@abstractmethod
def fun(self):
pass
class foo(headers):
def __init__(self):
print('__init__')
def fun(self):
print('foo.fun')
f = foo()
f.fun()
浙公網(wǎng)安備 33010602011771號