Python高效编程(五)

作者: dreamkong | 来源:发表于2017-10-26 15:51 被阅读8次

    实际编程和面试都会遇到的典型问题。


    图片来源于网络

    如何派生内置不可变类型并修改其实例化行为

    #我们想自定义一种新类型元组,对于传入的可迭代对象,我们只想保留其中int类型>0的元素 新类型是内置tuple的子类
    
    class IntTuple(tuple):
        def __new__(cls,iterable):
            # 使用生成器过滤
            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
    

    如何为创建大量实例节省内存

    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多了{'__dict__', '__weakref__'}
    # '__dict__'可以动态绑定
    p1.x = 123
    del p1.__dict__['x']
    
    import sys
    # 占用了320内存
    sys.getsizeof(p1.__dict__)
    
    # p2事先定义__slots__ 声明了实例属性名字的列表
    # p2就无法动态绑定 从而节省了内存
    # p2.x = 123
    

    如何创建可管理的对象属性

    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
    

    如何使用描述符对实例属性做类型检查

    # 描述符 __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
    

    如何通过实例方法名字的字符串调用方法

    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)))
    

    相关文章

      网友评论

        本文标题:Python高效编程(五)

        本文链接:https://www.haomeiwen.com/subject/ciskpxtx.html