首页 » 编程 » Python » Python学习 » 面向对象 » 正文

内置方法

一、isinstance(obj,cls)和issubclass(sub,super)

isinstance(obj,cls) 检查obj是否是类cls的对象

class Foo:
    pass

obj = Foo()
print(isinstance(obj, Foo))  # 输出:True
s = “alex”
print(isinstance(s, str))  # 输出:True

 

issubclass(sub, super) 检查sub类是否是super类的派生类(子类)

class Foo:
    pass

class Bar(Foo):
    pass

print(issubclass(Bar, Foo)) # 输出:True

 

二、反射

反射

 

三、item系列:__setitem__,__delitem__,__getitem__

tips:Python里凡是以__开头的方法,都是在某些时候会触发它的执行。

 

通过这三个方法可以将操作对象属性做成像操作字典一样去操作属性,来看下面的例子:

class Foo:
    def __init__(self, name):
        self.name = name

    def __getitem__(self, item):
        # print("getitem...")
        # print(item)
        return self.__dict__.get(item)  # 查找字典里是否有name这个key,有就返回,没有就返回None

    def __setitem__(self, key, value):
        # print("setitem...")
        # print(key, value)
        self.__dict__[key] = value

    def __delitem__(self, key):
        # print("delitem...")
        # print(key)
        self.__dict__.pop(key)


obj = Foo("alex")
# getitem
# 以前调用对象的属性的时候是这样的
# print(obj.name)  # 相当于 obj.__dict__["name"]
# 假如写成下面这种形式
print(obj["name"])  # 自动触发 __getitem__ 方法的执行,"name"传给了item,在方法里查找字典里是否有name这个key,有就返回,没有就返回None

# setitem
# 以前设置属性是这样的
# obj.x=1
# 现在可以写成下面这种形式:
obj["x"] = 1  # 自动触发 __setitem__ 方法的执行,"x" 传给了key,1传给了value,在方法里给__dict__添加了这个新的属性
print(obj.__dict__)  # 输出;{'name': 'alex', 'x': 1}  x属性添加成功了。

# delitem
# 以前删除属性的时候是这样的
# del obj.name
# print(obj.__dict__) # 输出:{'x': 1} ,name成功删除了
# 现在可以写成下面这种形式
del obj["name"]  # 自动触发 __delitem__ 方法的执行,"name"传给了key,在方法里删除了 __dict__ 的key:name
print(obj.__dict__)  # 输出:{'x': 1} ,name成功删除了

 

四、__str__方法

# d = {"name": "alex"}  本质为如下:
d = dict({"name": "alex"})
print(d)  # 输出:{'name': 'alex'}

理论上d为dict的对象,输出的时候应该输出类似于下面这样的:

<__main__.Foo object at 0x000001AF995B7320>

但是它却直接输出了字典的内容,怎么做到的呢?

 

通过 __str__ 方法来实现,来看下面的例子:

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("alex", 18)
print(p)  # 输出:<name:alex> <age:18>  #类里有__str__方法的时候,print的时候就会自动触发__str__方法的执行,方法里只能返回字符串类型

 

五、__del__方法

引子:

来看下面这个例子:

f = open("test.py")
f.close()
print(f)

首先看 f = open(“test.py”) ,实际上这一步操作有两个维度的操作:一个是应用级别的,一个是操作系统级别的。

应用级别:他就是一个基本的赋值操作,因为有等号,就和x=1, y=2 是一样的

系统级别:open告诉操作系统要打开指定的文件。

在应用级别,我们知道在程序结束后,python会自动帮助我们回收没有用到的内存,比如这里的 f = open(“test.py”) ,在内存中实际上开辟了两块内存空间,一个空间来存f,另一个空间是系统级别打开了这个文件,假如我们没有写f.close() 在程序结束后python是会自动帮助我们回收到f的内存的,但是python无法回收系统级别的内存,所以f.close()就是告诉系统进行内存回收,避免应用级别 f 已经没有用了,而系统却依然保持文件在打开状态。

我们在f.close()之后再打印一下 f 也能够打印出东西,是因为f.close()只是告诉系统进行内存回收,而程序并没有结束,所以f还存在在应用级别的内存中,所以能够打印,但是就不能够进行f.read()的操作了,因为f.read()也是告诉系统要读里面的内容,但是系统级别已经关闭文件了,所以是不能够在f.read()的。

通过上面的描述,我们知道了python会自动帮助我们回收内存,但是系统级别python做不到,所以程序结束前要告知系统进行内存回收,那假如就确实忘记写 f.close()了怎么办呢?之前有学过with操作,这里不考虑他,我们来探究本质,来看下面的例子:

class Open:
    def __init__(self, filename):
        print("打开文件")
        self.filename = filename

    def __del__(self):
        print("回收操作系统资源...")


f = Open("test.py")

print("---程序运行结束---")

运行结果如下:

打开文件
---程序运行结束---
回收操作系统资源...

可以看出,在类中当存在__del__方法的时候,在程序运行结束后会自动触发__del__方法的执行,所以以打开文件为例,当忘记写f.close()的时候,就可以在__del__方法里写上相应的操作来释放资源。

 

在来看一下:

class Open:
    def __init__(self, filename):
        print("打开文件")
        self.filename = filename

    def __del__(self):
        print("回收操作系统资源...")



f = Open("test.py")
del f
print("---程序运行结束---")

运行结果如下:

打开文件
回收操作系统资源...
---程序运行结束---

这里使用del f 手动对f进行了回收,在程序结束前首先触发了__del__方法的执行。

 

 

 

赞 (0)

发表评论

*