类的相关方法


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

定义类的__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

(0)
上一篇 2022年7月21日 00:21
下一篇 2022年7月21日 00:22

相关推荐

发表回复

登录后才能评论