如何为创建大量实例节省内存:
定义类的__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 函数调用

搜索
复制
<iframe></iframe>
原创文章,作者:wure,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/275730.html