Python高效編程(五)

實(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)))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,538評(píng)論 19 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,642評(píng)論 18 399
  • 當(dāng)今男孩沒(méi)找到女朋友的時(shí)候,會(huì)有很多標(biāo)準(zhǔn),男神或許喜歡嬌小可人溫柔,屌絲或許喜歡美麗性感尤物,其實(shí)每個(gè)人都有很多標(biāo)...
    Y羊兒閱讀 256評(píng)論 0 0
  • 睜開(kāi)眼是一個(gè)春夢(mèng) 閉上眼是一場(chǎng)恐懼 人們叫它失眠癥
    娃哈哈烏拉拉閱讀 168評(píng)論 2 1
  • 6
    紅昔昔閱讀 118評(píng)論 0 2

友情鏈接更多精彩內(nèi)容