Python从入门到实践:面向对象之内置方法六

Python的Class机制内置了很多特殊的方法来帮助使用者高度定制自己的类,这些内置方法都是以双下划线开头和结尾的,会在满足某种条件时自动触发。

1.__str__

str_方法会在对象被打印时自动触发,print功能打印的就是它的返回值,我们通常基于方法来定制对象的打印信息,该方法必须返回字符串类型

>>> class People:
...     def __init__(self,name,age):
...         self.name=name
...         self.age=age
...     def __str__(self):
...         return '<Name:%s Age:%s>' %(self.name,self.age) #返回类型必须是字符串
... 
>>> p=People('lili',18)
>>> print(p) #触发p.__str__(),拿到返回值后进行打印
<Name:lili Age:18>

2.__del__(析构函数)

del_会在对象被删除时自动触发。由于Python自带的垃圾回收机制会自动清理Python程序的资源,所以当一个对象只占用应用程序级资源时,完全没必要为对象定制_del_方法,但在产生一个对象的同时涉及到申请系统资源(比如系统打开的文件、网络连接等)的情况下,关于系统资源的回收,Python的垃圾回收机制便派不上用场了,需要我们为对象定制该方法,用来在对象被删除时自动触发回收系统资源的操作

class MySQL:
    def __init__(self,ip,port):
        self.conn=connect(ip,port) # 伪代码,发起网络连接,需要占用系统资源
    def __del__(self):
        self.conn.close() # 关闭网络连接,回收系统资源
 
obj=MySQL('127.0.0.1',3306) # 在对象obj被删除时,自动触发obj.__del__()

3.__init__

init()方法 当使用类名()创建对象时,Python解释器会自动执行以下操作:

A.为对象在内存中分配空间 创建对象

B.调用初始化方法为对象的属性设置初始值-初始化方法(init)

C.这个初始化方法是对象的内置方法,是专门用来定义一个类具有哪些属性的方法

4.__getattr__、__setattr__、__delattr__

之前介绍反射的时候说过,但是,这里有些许不同,内置方法里面没有hasattr

当使用obj.x = y的时候触发对象的setattr方法,当del obj.x的时候触发对象的delattr方法。
当尝试访问对象的一个不存在的属性时 obj.noexist 会触发getattr方法,getattr方法是属性查找中优先级最低的。
可以重写这3个方法来控制对象属性的访问、设置和删除
**特别注意:如果定义了getattr,而没有任何代码(即只有pass),则所有不存在的属性值都是None而不会报错,可以使用super().__getattr__()方法来处理**

class Student:
    def __getattr__(self, item):
        print('访问一个不存在的属性时候触发')
        return '不存在'

    def __setattr__(self, key, value):
        print('设置一个属性值的时候触发')
        # self.key = value  # 这样会无限循环
        self.__dict__[key] = value

    def __delattr__(self, item):
        print('删除一个属性的时候触发')
        if self.__dict__.get(item, None):
            del self.__dict__[item]

stu = Student()
stu.name = 'zlw'  # 设置一个属性值的时候触发
print(stu.noexit)  # 访问一个不存在的属性时候触发 , 返回'不存在'
del stu.name  # 删除一个属性的时候触发

5.__iter__、__next__

这2个方法用于将一个对象模拟成序列。内置类型如列表、元组都可以被选代,文件对象也可以被选代获取每一行内容。重写这两个方法就可以实现自定义的选代对象。

class MyRange():
    def __init__(self,begin,end,step):
        self.begin=begin
        self.end=end
        self.step=step
        self.count=0

    def __iter__(self):
        return self

    def __next__(self):
        if self.begin <self.end:
            self.count=self.begin
            self.begin=self.begin+self.step
            return self.count
        else:
            raise StopIteration('已经到达临界')

if __name__=='__main__':
    ra=MyRange(1,20,3)
    for item in ra:
        print(item)

----------------------------------------------------------------------------------------

6.item类和__len__

在深度学习中,我们在封装dataset的时候,一定会重写的两个内置方法,非常重要!!



class Person:

    def __getitem__(self,key):   # 获取
        return self.__dict__[key]

    def __setitem__(self,key,value):    #设置
        self.__dict__[key] = value

    def __delitem__(self,key):    #删除
        self.__dict__.pop(key)

p = Person()
p['a'] = 1
print(p['a'])
del p['a']
print(p['a'])    #这里会报KeyError

#使用len()时执行

class Life:
    def __init__(self,name,length):
        self.name = name
        self.length = length

    def __len__(self):
        return self.length

hsr = Life('hsr',100)
print(len(hsr))

7.__hash__

hash()用于获取一个对象(字符串、数字、对象)的哈希值,不能直接作用于list、set、dict

在hash()最用对象时,所得的结果不仅和对象的内容有关,还和对象的id(),也就是内存地址相关。

hash() 函数的对象字符不管有多长,返回的 hash 值都是固定长度的,也用于校验程序在传输过程中是否被第三方(木马)修改,如果程序(字符)在传输过程中被修改hash值即发生变化,如果没有被修改,则 hash 值和原始的 hash 值吻合,只要验证 hash 值是否匹配即可验证程序是否带木马(病毒)。

#对对象进行hash运算
class Student:
    def __init__(self,no,name):
        self.no = no
        self.name = name

    def __hash__(self):
        return hash(str(self.no)+self.name)

s = Student(102302,'hsr')
print(hash(s))

8.__eq__

class Life:
    def __init__(self,name,length):
        self.name = name
        self.length = length

    def __len__(self):
        return self.length

    def __eq__(self, other):
        return other.length == self.length  #重写后,判断的是长度是否相等,如果不重写,因为地址不一样,就不相等

hsr = Life('hsr',100)
ttt = Life('ttt',100)
print(hsr == ttt)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340