Python面向物件進階
阿新 • • 發佈:2018-12-11
二分
- 二分的前提是有序
- 時間複雜度為O(log n)
bisect模組
- bisect系,用於查詢index
bisect.bisect_left
bisect.bisect_right
- insort系,用於實際插入
bisect.insort_left
- 預設重複時從右邊插入
類的多繼承
- 用途:在子類上實現對基類的增強、實現多型
- OCP原則:多用繼承,少修改
Mixin類
- 將其他類混合,同時帶來類的屬性和方法
Mixin
類可以繼承,本質是多繼承實現的- 使用規則:
Mixin
類中不顯式出現__init__
初始化方法- 混入其他類中實現部分功能,無法獨立工作
Mixin
Mixin
類Mixin
類通常在繼承列表中的第一個位置
魔術方法
- hash值相同只是hash值衝突,物件不一定相等,使用
set
並不一定去重 - 去重需要提供
__eq__
方法 list
類例項原始碼中有__hash__ = None
,則其不可hash
容器相關方法
__len__
- 返回物件的長度,若無
__bool__
方法則檢視__len()__
方法是否存在,存在返回非0為真;空字典
、空元組
、空集合
、空列表
、空字串
長度為0,等效False
- 返回物件的長度,若無
__iter__
- 迭代容器,返回一個新的迭代器物件
__contains__
- in成員運算子,未實現則呼叫
__iter__
- in成員運算子,未實現則呼叫
__getitem__
- 實現
self[key]
訪問,key
為hashable
,不存在則KeyError
異常
- 實現
__setitem__
- 設定值的方法
__missing__
- 字典或其子類使用
__getitem()__
呼叫時,key不存在則執行此方法
- 字典或其子類使用
可呼叫物件
__call__
- 類中定義該方法,例項化得到其例項,則例項可像函式一樣呼叫
# 定義fib數列的類 class Fib: def __init__(self): self.item = [0, 1, 1] def __call__(self, index): if index < 0: raise IndexError('Wrong Index') if index < len(self.item): return self.item[index] for i in range(3, index + 1): self.item.append(self.item[i-1] + self.item[i-2]) return self.item[index] print(Fib()(100))
上下文管理
# 將類作為裝飾器,使用上下文管理方法顯示函式執行時長
import time, datetime
from functools import wraps, update_wrapper
class TimeIt:
'''This is A Class'''
def __init__(self, fn):
self.fn = fn
# 把函式物件的文件字串賦值給類
# self.__doc__ = fn.__doc__
# update_wrapper(self, fn)
wraps(fn)(self)
def __enter__(self):
self.start = datetime.datetime.now()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.delta = (datetime.datetime.now() - self.start).total_seconds()
print('{} took {} second(s).context'.format(self.fn.__name__,self.delta))
def __call__(self, *args, **kwargs):
self.start = datetime.datetime.now()
ret = self.fn(*args, **kwargs)
self.delta = (datetime.datetime.now() - self.start).total_seconds()
print('{} took {} second(s).call'.format(self.fn.__name__,self.delta))
return ret
@TimeIt
def add(x, y):
'''This is add function'''
time.sleep(3)
return x + y
print(add(4, 5))
print(add.__doc__)
print(TimeIt(add).__doc__)
反射
- 定義:通過一個物件,找出其type,class,attribute,method的能力
- 反射能力的函式:
type()
,isinstance()
,callable()
,dir()
,getattr()
描述器
- 屬性查詢順序
- 例項的
__dict__
優先於非資料描述器 - 資料描述器優先於例項的
__dict__
- 例項的
# 類staticmethod裝飾器
class StaticMethod:
def __init__(self,fn):
self.fn=fn
def __get__(self, instance, owner):
return self.fn
class A:
@staticmethod
def cmd():
print('static method')
A.cmd() # static method
A().cmd() # static method
# 類staticmethod裝飾器
class StaticMethod:
def __init__(self,fn):
self.fn=fn
def __get__(self, instance, owner):
return self.fn
class A:
@staticmethod
def cmd():
print('static method')
A.cmd()
A().cmd()
# 類classmethod裝飾器
class ClassMethod:
def __init__(self, fn):
self.fn = fn
def __get__(self, instance, owner):
ret = self.fn(owner)
return ret
class A:
@ClassMethod
def clscmd(cls):
print(cls.__name__)
print(A.__dict__)
A.clscmd