类的相关方法
如何为创建大量实例节省内存:
定义类的__slots__ 它声明实例属性名字的列表,减少内存开销
#定义两个类: 查看占用内存大小 class player1(): def __init__(self,uid,name,status=0,level=1): self.uid = uid self.name = name self.status = status self.level = level class player2(): __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 比p2 要多占用内存,主要是p1比p2 对了一个__dict__ 方法 ,这样之前定义好的属性是不可以动态添加的 p1 = player1(1,'xiao') p2 = player2(1,'long') # p2这是没有__dict__方法的 print(p1.__dict__) # 返回{'uid': 1, 'name': 'xiao', 'status': 0, 'level': 1} # sys 模块中getsizeof() 方法可以查看内存使用多少 import sys print(sys.getsizeof(p1.__dict__))
如何让对象实现上下文管理:
实例:实现一个telnet客户端的类调用实例的start方法启动客户端服务,交互完毕后调用clearup方法关闭链接,以及进行历史记录写入文件
实现上下文管理需要定义__enter__ __exit__ 方法他们分别在with开头和结束时调用
from telnetlib import Telnet from sys import stdin,stdout from collections import deque class Telnetclient(object): def __init__(self,addr,port=23): self.addr = addr self.port = port self.tn = None def start(self): # 用户 t = self.tn.read_until('login:') stdout.write(t) user = stdin.readlines() self.tn.write(user) #密码 t = self.tn.read_until('passwd:') if t.startswith(user[:-1]): t = t[len(user) + 1:] stdout.write(t) self.tn.write(stdin.readlines()) t = self.tn.read_until("$ ") stdout.write(t) while True: uinput = stdin.readline() if not uinput: break self.history.append(uinput) self.tn.write(uinput) t = self.tn.read_until('$ ') stdout.write(t[len(uinput) + 1:]) def __enter__(self): # 启动前执行 self.tn = Telnet(self.addr,self.port) self.history = deque() return self def __exit__(self, exc_type, exc_val, exc_tb): # 结束后执行 self.tn.close() self.tn = None with open(self.addr + '_history.txt','w') as f: # 记录历史 f.writelines(self.history) with Telnetclient('127.0.0.1') as client: client.start()
如何管理对象属性:
一般对实例属性通过get方式,或set方法进行获取和设计
实例: 下面以一个圆来实验
通过使用prope'rty函数为实例创建可管理属性, 直接访问属性,其实他内部时调用的对应的方法
class Circle(object): def __init__(self,radius): self.radius = radius def getRadius(self): # 获取圆半径 return self.radius def setRadius(self,value): # 设置半径 if not isinstance(value,(int,float)): raise ValueError("error value") self.radius = float(value) def getArea(self): return self.radius ** 2 * 3.14 R = property(getRadius,setRadius) # 可以用属性方式调用方法 c = Circle(3.2) print(c.R) c.R = 5.9
如何让类支持比较操作
比较操做在类里面实现 __lt__ , __gt__, __le__, __ge__ ,__eq__, __ne__ 这些方法
也可以使用标准库functools 下的装饰器total_ordering可以简化此过程
采用这个装饰器吗,只需定义一个eq , 大于小于定义任何一个
如何使用描述符对实例属性做类型检查?
实现__get__ , __set__ , __delete__ 这些方法 就是描述符
在__set__ 内使用isinstance 函数做类型检查
如何通过字符串名字来调用方法:
使用getattr 方法通过名字来调用方法 或者使用operator 下的methodcaller 函数调用