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 条评论
登录 后参与评论

相关文章

来自专栏wannshan(javaer,RPC)

dubbo路由代码分析3(condition路由器)

这篇说说,dubbo condition类型路由器的路由解析和执行过程 由 https://cloud.tencent.com/developer/artic...

3349
来自专栏三流程序员的挣扎

RxJava 算术和聚合操作符

将依次连续发送 observableStr,observableInt,observableBoolean 里的 12 个数据。

1164
来自专栏程序猿DD

你真的了解lambda吗?一文让你明白lambda用法与源码分析

本文链接: http://www.cmlanche.com/2018/07/22/lambda用法与源码分析/

602
来自专栏Brian

Python With-As

深入理解Python的With-as语句 ---- 学习Python有一段时间了,最近做一个项目会涉及到文件的读取和关闭。比如:我想把一些对象序列化到文件里面,...

4547
来自专栏Java帮帮-微信公众号-技术文章全总结

Java面试系列7

Java面试系列7 1.HashMap和Hashtable的区别。 HashMap是Hashtable的轻量级实现(非线程安全的实现),二者都实现了Map 接...

2964
来自专栏Java编程

Java习惯用法总结

在Java编程中,有些知识 并不能仅通过语言规范或者标准API文档就能学到的。在本文中,我会尽量收集一些最常用的习惯用法,特别是很难猜到的用法。(Joshua ...

1K3
来自专栏JMCui

读书笔记 之《Thinking in Java》(对象、集合、异常)

一、前言:     本来想看完书再整理下自己的笔记的,可是书才看了一半发现笔记有点多,有点乱,就先整理一份吧,顺便复习下前面的知识,之后的再补上。     真的...

3588
来自专栏微信公众号:Java团长

Java习惯用法总结

在Java编程中,有些知识 并不能仅通过语言规范或者标准API文档就能学到的。在本文中,我会尽量收集一些最常用的习惯用法,特别是很难猜到的用法。

711
来自专栏阮一峰的网络日志

async 函数的含义和用法

本文是《深入掌握 ECMAScript 6 异步编程》系列文章的最后一篇。 Generator函数的含义与用法 Thunk函数的含义与用法 co函数库的含义...

2666
来自专栏大内老A

采用一个自创的"验证框架"实现对数据实体的验证[改进篇]

自《编程篇》和《设计篇》发布以来,收到了一些反馈。尤其是园友双鱼座提到.NET 3.5下的System.ComponentModel.DataAnnotatio...

1989

扫码关注云+社区