[优雅的面试]你了解python的对象吗Python

本文正在参加「Python主题月」,详情查看 活动链接

微信公众号搜索【程序媛小庄】,活得快乐的最重要因素是人生有事干、有人可去爱,以及生命中有所冀望。

前情提要:小庄面试,结果面试官着急去吃饭~又约了这次来面,不晓得又会问什么问题呢?

面试官大佬:小伙子来的挺准时的(赞赏的表情~),今天咱们接着聊哈,小伙子,你有对象了没?

我:(心想难道面试官这么热情,我要是没有对象难道还要给我介绍一个?)托您的福,已经有了。

面试官大佬:既然有对象了,那咱们今天就来聊聊对象那些个事儿吧!

我:(心中了然,原来是想要文面向对象,妥妥的没问题)好的,您请说。

面试官大佬:Python是一门面向对象的语言,你是怎么理解对象这个概念的呢?

我:面向对象在python中一直都有一个抽象的说法,就是一切皆对象,就我个人理解而言,对象就是一些数据和一些操作数据的方法的集合体,比如我们自定义一个类,那么这个类中就会有一些数据和方法,就像工具箱一样,里面既有螺丝也有螺丝刀,共同组成了工具箱这个对象,螺丝就相当于数据而螺丝刀就是方法。

面试官大佬:你说说对象绑定定方法、静态方法和类方法?

我:对象绑定方法是类实例化得到的对象可以直接调用的方法,会将实力当做第一个参数传递给该方法,如果是类调用这个方法就需要传递一个参数,就是这个类的示例;类方法是classmethod,是一个装饰器,将类中定义的方法装饰成为类方法,当调用类方法的时候就会将类当做第一个参数传递给该方法;静态方法是staticmethod,也是一个装饰器,静态方法就没有任何自动传递参数的效果了,不管是类调用还是类实例化得到的对象调用都没有自动传参的效果,当不需要类和示例中的任何信息或者属性的情况下可以考虑使用静态方法。

面试官大佬:那你再说说反射。

我:在python中反射指的是通过字符串来操作对象的属性,涉及到四个内置函数的使用

getattr(obj, 'name')  获取对象的属性值
hasattr(obj, 'name')  判断对象是否有某个属性值
setattr(obj, 'name')  修改/增加对象的属性值
delattr(obj, 'name')  删除对象的属性
复制代码

通过使用反射就可以在事先不知道对象有什么属性的情况下在程序中分析出对象的属性。反射的底层原理就是先通过dir方法查看一个对象属性,然后由__dict__字典通过字符串反射到真正的属性上,得到属性值。

基于反射可以十分灵活的操作对象的属性,比如说django中的CBV,利用反射的原理,视图类里面书写的get方法或者post方法会根据请求方式的不同自动调用。

面试官大佬:写过元类吗,或者了解元类吗

我:(实话实说)在公司开发中没有写过元类,但是了解一些元类的原理。

面试官大佬:嗯嗯,没事儿,那你就说说你知道的元类的一些原理或者知识。

我:类实例化产生对象,在python中类也是对象,而元类实例化就会得到类这个对象,class关键字定义的所有的类和内置的类都是由元类type实例化产生的。我们是可以通过控制调用类的步骤自定义元类,在调用在调用类的时候首先执行的是类中的__new__方法,该方法必须返回一个空对象,就是创建一个实例,如果没有返回值在实例化对象的时候就不会运行类的__init__方法,__init__方法是初始化实例,为空对象设置初始值。如果想让一个对象可以加括号调用,需要在该对象的类中添加一个__call__方法,就是对象加括号可以调用是因为调用了产生这个对象的类中的__call__方法。类加括号可以调用是调用了元类中的__call__方法,元类中的__call__方法会先调用类中的__new__方法,再调用类中的__init__方法,最后元类中的__call__方法会返回一个初始化好的对象。

面试官大佬:原理掌握的不错,元类大概就是这么回事,好了小伙子,你这对象找的不错,面向对象就先到这,下次咱们再聊聊网络和并发这块。

我:好嘞~您走好