
*****
## 類與對象深度問題與解決技巧
### 1.如何派生內置不可變類型并修改其實例化行為
我們想自定義一種新類型的元組,對于傳入的可迭代對象,我們只保留其中int類型且值大于0的元素,例如:
```
IntTuple([2,-2,'jr',['x','y'],4]) => (2,4)
```
如何繼承內置tuple 實現IntTuple
### 2.如何為創建大量實例節省內存
在游戲中,定義了玩家類player,每有一個在線玩家,在服務器內則有一個player的實例,當在線人數很多時,將產生大量實例(百萬級)
<br>如何降低這些大量實例的內存開銷?
<br>解決方案:
- 定義類的\_\_slots\_\_屬性,聲明實例有哪些屬性(關閉動態綁定)
### 3.Python中的with語句
上下文管理器協議
### contextlib簡化上下文管理器
~~~
import contextlib
@contextlib.contextmanager
def file_open(filename):
print("file open")
yield {}
print("file end")
with file_open('lib1.py') as f:
print("file operation")
~~~
### 4.如何創建可管理的對象屬性
在面向對象編程中,我們把方法看做對象的接口。直接訪問對象的屬性可能是不安全的,或設計上不夠靈活,但是使用調用方法在形式上不如訪問屬性簡潔。
### 5.如何讓類支持比較操作
有時我們希望自定義類的實例間可以使用,<,<=,>,>=,==,!=符號進行比較,我們自定義比較的行業,例如,有一個矩形的類,比較兩個矩形的實例時,比較的是他們的面積
### 6.如何在環狀數據結構中管理內存
雙向循環鏈表
~~~
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
def add_right(self, node):
self.right = node
node.left = self
def __str__(self):
return 'Node:<%s>' % self.data
def __del__(self):
print('in __del__: delete %s' % self)
def create_linklist(n):
head = current = Node(1)
for i in range(2, n + 1):
node = Node(i)
current.add_right(node)
current = node
return head
head = create_linklist(1000)
head = None
import time
for _ in range(1000):
time.sleep(1)
print('run...')
input('wait...')
~~~
### 通過實例方法名字的字符串調用方法
我們有三個圖形類
~~~
Circle,Triangle,Rectangle
~~~
他們都有一個獲取圖形面積的方法,但是方法名字不同,我們可以實現一個統一的獲取面積的函數,使用每種方法名進行嘗試,調用相應類的接口
~~~
class Triangle:
def __init__(self,a,b,c):
self.a,self.b,self.c = a,b,c
def get_area(self):
a,b,c = self.a,self.b,self.c
p = (a+b+c)/2
return (p * (p-a)*(p-b)*(p-c)) ** 0.5
class Rectangle:
def __init__(self,a,b):
self.a,self.b = a,b
def getArea(self):
return self.a * self.b
class Circle:
def __init__(self,r):
self.r = r
def area(self):
return self.r ** 2 * 3.14159
~~~