Python高效编程(五)

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

图片来源于网络

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

#我们想自定义一种新类型元组,对于传入的可迭代对象,我们只想保留其中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)))

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏coder修行路

面向对象编程进阶

1、   静态方法staticmethod 只是名义上归类管理,实际上再静态方法里访问不了类和实例中的任何属性 定义: 通过@staticmethod装饰器即可...

2089
来自专栏javathings

为什么重写 equals 时必须重写 hashcode?

equals 默认是和==一样,判断引用是否相等的,一般需要覆写后才能实现真正的判等。

1002
来自专栏温安适的blog

JDK1.8下关于MethodHandle问题

3748
来自专栏积累沉淀

Java设计模式(二十一)----访问者模式

访问者模式 一、概述 1、定义 2、分派的概念 3、分派的类型 4、双重分派 二、结...

19610
来自专栏Python小屋

对Python列表进行封装和二次开发实现自定义栈结构

设计自定义栈类,模拟入栈、出栈、判断栈是否为空、是否已满以及改变栈大小等操作。 class Stack: #构造方法 def __init__(self, ...

3047
来自专栏决胜机器学习

PHP数据结构(三)——运用栈实现括号匹配

PHP数据结构(三)——运用栈实现括号匹配 (原创内容,转载请注明来源,谢谢) 栈在数据结构上是一种特殊的线性表,其限制是仅允许在表的一端进行插入和删除运算,...

3906
来自专栏光变

3.1 ASM-方法-结构

ASM-方法-结构 本章将会介绍如果使用ASM core API生成或者转换Java编译后的method。 本将开始会展示编译后的method,然后使用很多说...

972
来自专栏小李刀刀的专栏

Unicode编解码函数

在用XMLHTTP进行远程数据传输的时候,如果涉及到不同编码,比如从oblog向我的博客发送一个trackback ping,数据中包含的中文字符就会出现乱码。...

3105
来自专栏码匠的流水账

聊聊storm trident的state

storm-2.0.0/storm-client/src/jvm/org/apache/storm/trident/state/StateType.java

1074
来自专栏专注 Java 基础分享

深入理解循环队列----循环数组实现ArrayDeque

     我们知道队列这种数据结构的物理实现方式主要还是两种,一种是链队列(自定义节点类),另一种则是使用数组实现,两者各有优势。此处我们将要介绍的循环队列其实...

2408

扫码关注云+社区