實(shí)際編程和面試都會(huì)遇到的典型問(wèn)題。

圖片來(lái)源于網(wǎng)絡(luò)
如何派生內(nèi)置不可變類型并修改其實(shí)例化行為
#我們想自定義一種新類型元組,對(duì)于傳入的可迭代對(duì)象,我們只想保留其中int類型>0的元素 新類型是內(nèi)置tuple的子類
class IntTuple(tuple):
def __new__(cls,iterable):
# 使用生成器過(guò)濾
g = (x for x in iterable if isinstance(x,int) and x > 0)
return super(IntTuple,cls).__new__(cls,g)
def __init__(self,iterable):
super(IntTuple,self).__init__()
it = IntTuple([1,-2,3,'x'])
it
如何為創(chuàng)建大量實(shí)例節(jié)省內(nèi)存
class Player(object):
def __init__(self,uid,name,status=0,level=1):
self.uid = uid
self.name = name
self.status = status
self.level = level
class Player2(object):
__slots__ = ['uid','name','status','level']
def __init__(self,uid,name,status=0,level=1):
self.uid = uid
self.name = name
self.status = status
self.level = level
p1 = Player('001','uu')
p2 = Player2('001','uu')
set(dir(p1)) - set(dir(p2))
# p1比p2多了{(lán)'__dict__', '__weakref__'}
# '__dict__'可以動(dòng)態(tài)綁定
p1.x = 123
del p1.__dict__['x']
import sys
# 占用了320內(nèi)存
sys.getsizeof(p1.__dict__)
# p2事先定義__slots__ 聲明了實(shí)例屬性名字的列表
# p2就無(wú)法動(dòng)態(tài)綁定 從而節(jié)省了內(nèi)存
# p2.x = 123
如何創(chuàng)建可管理的對(duì)象屬性
from math import pi
class Cricle(object):
def __init__(self,radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self,value):
if not isinstance(value,(int,float)):
raise ValueError('wrong type')
self._radius = value
def getArea(self):
return self._radius ** 2 * pi
c = Cricle(5)
c.radius
如何讓類支持比較操作
from math import pi
from functools import total_ordering
@total_ordering
class Cricle(object):
def __init__(self,radius):
self._radius = radius
def area(self):
return self._radius ** 2 * pi
def __lt__(self,obj):
return self.area() < obj.area()
def __eq__(self,obj):
return self.area() == obj.area()
c1 = Cricle(3)
c2 = Cricle(5.0)
c1 > c2
如何使用描述符對(duì)實(shí)例屬性做類型檢查
# 描述符 __get__ __set__ __del__
class Attr(object):
def __init__(self,name,type_):
self.name = name
self.type_ = type_
def __get__(self,instance,cls):
return instance.__dict__[self.name]
def __set__(self,instance,value):
if not isinstance(value,self.type_):
raise TypeError('expected an %s'%self.type_)
instance.__dict__[self.name] = value
def __delete__(self,instance):
del instance.__dict__[self.name]
class Person(object):
name = Attr('name',str)
age = Attr('age',int)
height = Attr('height',float)
p = Person()
p.name = '123'
p.age = 123
p.height = 1.0
如何通過(guò)實(shí)例方法名字的字符串調(diào)用方法
class Circle(object):
def __init__(self,r):
self.r = r
def area(self):
return self.r ** 2 * 3.14
class Rectangle(object):
def __init__(self,w,h):
self.w = w
self.h = h
def get_area(self):
return self.w * self.h
class Triangle(object):
def __init__(self,a,b,c):
self.a = a
self.b = b
self.c = c
def getArea(self):
#海倫公式:√[p(p-a)(p-b)(p-c) ]其中p=1/2(a+b+c)
p = (self.a + self.b + self.c) / 2
return (p * (p - self.a) * (p - self.b) * (p - self.c)) ** 0.5
def getArea(shape):
for name in ('area','get_area','getArea'):
f = getattr(shape,name,None)
if f:
return f()
shape1 = Circle(3)
shape2 = Rectangle(5,6)
shape3 = Triangle(3,4,5)
shapes = [shape1,shape2,shape3]
print(list(map(getArea,shapes)))