52----面向对象高级方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/c_first/article/details/82229488

__str__:

如下代码,list是个类,People也是类,但是对象shuai打印出来是内存地址,而对象l打印出来的是l本身的信息

class People:
    home = "china"
    def __init__(self,name):
        self.name = name

    def talk(self):
        print("hahaha")


shuai =People('shuai')
print(shuai)  # 打印内存地址   <__main__.People object at 0x000001B67F676BA8>

l = [1,2,3]
print(l)        # 打印l本身的信息 [1, 2, 3]

如上,也就是说class会有一种机制,能够让我们打印由一个类产生的对象时,能够打印出对象相关的信息,那就用到了内置的__str__()方法,这个绑定给对象的方法在打印的时候会触发,是默认触发的,就会打印出来内存地址,如上图的shuai

通过重写该方法,来自定义返回的内容

class People:
    home = "china"
    def __init__(self,name):
        self.name = name

    def talk(self):
        print("hahaha")

    def __str__(self):
        return '自定义内容'


shuai = People('shuai')
print(shuai)  #     自定义内容

如果不写返回的内容,提示返回了一个不是字符串的类型,所以知道,它必须返回字符串类型

class People:
    home = "china"
    def __init__(self,name):
        self.name = name

    def talk(self):
        print("hahaha")

    def __str__(self):
        pass


shuai = People('shuai')
print(shuai)        # TypeError: __str__ returned non-string (type NoneType)

__del__:

如下代码,对象f产生后,就会在内存中,知道文件关闭被释放掉,或者执行del 删除掉

class Test:
    def __init__(self, x):
        self.num = x

f = Test(5)
print(f.num)

del f

内置函数__del__(),会在整个程序执行完后,触发对象的绑定方法__del__(),通常该方法用来写一些清理操作

在使用del时,del删除完成后,会触发__del__()

class Test:
    def __init__(self, x):
        self.num = x

    def __del__(self):
        print("执行del")

f = Test(5)
# del f  # 执行del
print(f.num)

# 5
# 执行del

如果产生的对象仅仅只是python程序级别的(用户级),那么无需定义__del__,如果产生的对象的同时还会向操作系统发起系统调用,即一个对象有用户级与内核级两种资源,比如(打开一个文件,创建一个数据库链接),则必须在清除对象的同时回收系统资源,这就用到了__del__,通过重写__del__ 来进行其他操作

典型的应用场景:

扫描二维码关注公众号,回复: 3119291 查看本文章

创建数据库类,用该类实例化出数据库链接对象,对象本身是存放于用户空间内存中,而链接则是由操作系统管理的,存放于内核空间内存中

当程序结束时,python只会回收自己的内存空间,即用户态内存,而操作系统的资源则没有被回收,这就需要我们定制__del__,在对象被删除前向操作系统发起关闭数据库链接的系统调用,回收资源

f=open('a.txt') #做了两件事,在用户空间拿到一个f变量,在操作系统内核空间打开一个文件
del f #只回收用户空间的f,操作系统的文件还处于打开状态
 
#所以我们应该在del f之前保证f.close()执行,即便是没有del,程序执行完毕也会自动del清理资源,于是文件操作的正确用法应该是
f=open('a.txt')
# 读写...
f.close()
# 很多情况下大家都容易忽略f.close,这就用到了with上下文管理

__getitem__、__setitem__、__delitem__:

 

如下代码,l是一个对象,d是一个对象,l[1]就是访问对象的一个熟悉,d["name"]也是访问对象的一个属性,但是通常访问对象的属性都是:obj.name 这种形式的

l = [1,2,3]

d = {"name": "bone"}

print(l[1])         # 2
print(d["name"])    # bone

如上,说明python中有支持中括号形式访问对象属性的方法

正常访问一个对象的属性

class Test:
    def __init__(self, name ,age):
        self.name = name
        self.age = age

f = Test("shuai", 18)
print(f.name)       # shuai
print(f.age)        # 18

1、实现使用中括号形式访问属性,需要重写__getitem__

class Test:
    def __init__(self, name ,age):
        self.name = name
        self.age = age

    def __getitem__(self, item):
        print(self)
        print(item)
        print(type(item))


f = Test("shuai", 18)
print(f.name)       # shuai
print(f.age)        # 18

# 上面打印没有触发__getitem__方法,需用通过【】形式触发

f["name"]       # <__main__.Test object at 0x000002AB74A1D438>        name      <class 'str'>

上面f["name"]拿到的是字符串name,不是变量name的值,那就可以用反射来实现

class Test:
    def __init__(self, name ,age):
        self.name = name
        self.age = age

    def __getitem__(self, item):

        # return getattr(self,item)
        return self.__dict__[item]


f = Test("shuai", 18)


# print(f["name"])        # shuai
print(f["name"])        # shuai

2、实现[]设置属性,__setitem__()

class Test:
    def __init__(self, name ,age):
        self.name = name
        self.age = age

    def __getitem__(self, item):

        # return getattr(self,item)
        return self.__dict__[item]

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


f = Test("shuai", 18)


print(f["name"])        # shuai
print(f.__dict__)       # {'name': 'shuai', 'age': 18}
f["name"] = "nb"
print(f.__dict__)       # {'name': 'nb', 'age': 18}

3、实现[]删除属性,__delitem__()

class Test:
    def __init__(self, name ,age):
        self.name = name
        self.age = age

    def __getitem__(self, item):

        # return getattr(self,item)
        return self.__dict__[item]

    def __setitem__(self, key, value):
        setattr(self, key, value)
        self.__dict__[key] = value

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



f = Test("shuai", 18)


print(f["name"])        # shuai
print(f.__dict__)       # {'name': 'shuai', 'age': 18}
f["name"] = "nb"
print(f.__dict__)       # {'name': 'nb', 'age': 18}

del f["name"]
print(f.__dict__)       # {'age': 18}

还有很多类似上面的方法。。。。。。。。。。。。。

所有的比如字符串、列表等等的内置方法,都支持上面的操作,重写自定义

 

 

猜你喜欢

转载自blog.csdn.net/c_first/article/details/82229488