Python中实例对象如何进行属性和方法调用原因分析
2018-03-09 17:10
1041 查看
在正式开始之前,我们先看一段代码:
下面我们来分析这段代码,上图的左边是实际的代码过程,右边为执行后的结果。
Python中一切皆对象。绝对不是一句空话,在Python的解释器里,不仅有自己定义是对象,使我们传统意义上认为一切东西都是对象,对于执行的代码、函数、以及数据类型,你都可以在Python的源代码中找到相应的类对象,因此他们也都是实例对象。在Python3中,一切对象皆有父类对象。所有对象都有继承父类对象,要么继承于 自定义的对象,要么继承自内置的父类对象即object 。因此只要是有自定义对象,总有一个自定义对象是继承自object对象的或者元类对象。
所有的实例对象都是由类对象创建的。那么你可能会问:“”那是类对象是由什么创建的呐?“”创建Python语言的龟叔在Python解释器中,定义了一个上帝类即type元类,所有的类对象都是由元类对象创建,元类对象自身创建自身。即类本身也是一个对象即类对象。
实例对象在创建时,由Python解释器自动赋予了一个特殊的属性即__class__(可以认为是魔法属性)。该属性的作用是:会找到相对应的实例对象的类对象内存地址。
我们知道我们在定义类时,将所有的实例方法和类方法以及静态方法是定义在类对象中的。那么实例对象是如何访问到实例方法和类方法以及静态方法的呐?这就是__class__属性的作用了,在内存中也确实是这种情况。文字不好描述,直接上图。
在创建实例对象后会自动执行初始化方法(__init(self,*args,**args)),将实例对象的属性进行初始化,并在内存中将实例对象的属性存储在实例对象的线性地址中(有兴趣的化可以去看看数据结构)。这样一来就可以通过实例对象直接访问实例属性。那么还是那个问题,定义类时,将所有的实例方法和类方法以及静态方法是定义在类对象中的。那么实例对象是如何访问到实例方法和类方法以及静态方法的呐?通过上图我们可以看到__class__属性的作用:当实例对象在自己的线性地址中找不到该实例方法时,会通过__class__属性去找到创建该实例对象的类对象,直接访问类对象中线性地址存储的属性和方法。这也就是实例对象可以调用实例方法和类方法以及静态方法及类属性的主要根本原因。
然而可能又有疑问了,为什么类对象不能调用实例方法和实例属性呐?
对于实例属性比较好解释:因为实例对象的属性是存储在实例对象的线性空间里,而类对象的__class__属性只能去找到创建该类对象的类对象的内存地址(可以理解为元类对象的内存地址),所以无法访问实例属性。
对于实例方法哪啊?有人可能会问:“”实例方法不是存储在类对象中吗?为什么类对象不能访问?“”这就要说到关于修饰器,(在这里就不累述修饰器的概念了,我会专门分一片文章去讲解,有兴趣的可以关注一下,我的博客,我会不定期的更新一些文章,分享我的一些经验和体会。)在 类对象中如果要去访问方法时,类对象会找修饰器关键字即@staticmethod或者@classmethod,经修饰器修饰过的方法才能被类对象调用。因此实例方法无法被类对象去调用。
总结:
说到这里,不知道会不会对你的疑惑有所帮助,在这里我做一下简单的总结。
所有的实例对象都必须有父类对象。
所有的实例对象都是由 元类 或者 解释器内置的类对象 以及 自定义的类对象 创建出来。
所有的对象都有__class__属性,是由创建对象时由解释器自动添加的属性。
类属性、实例方法、类方法、静态方法在内存中只保存⼀份。
实例属性在每个实例对象中都要保存⼀份。
实例⽅法:由对象调⽤;⾄少⼀个self参数;执⾏实例⽅法时,⾃动将调
⽤该⽅法的对象赋值给self。
类⽅法:由类调⽤; ⾄少⼀个cls参数;执⾏类⽅法时,⾃动将调⽤该⽅
法的类赋值给cls。
回顾上面图片中的代码,我们可以再去分析看看会不会有新的理解。
下面我们来分析这段代码,上图的左边是实际的代码过程,右边为执行后的结果。
Python中一切皆对象。绝对不是一句空话,在Python的解释器里,不仅有自己定义是对象,使我们传统意义上认为一切东西都是对象,对于执行的代码、函数、以及数据类型,你都可以在Python的源代码中找到相应的类对象,因此他们也都是实例对象。在Python3中,一切对象皆有父类对象。所有对象都有继承父类对象,要么继承于 自定义的对象,要么继承自内置的父类对象即object 。因此只要是有自定义对象,总有一个自定义对象是继承自object对象的或者元类对象。
所有的实例对象都是由类对象创建的。那么你可能会问:“”那是类对象是由什么创建的呐?“”创建Python语言的龟叔在Python解释器中,定义了一个上帝类即type元类,所有的类对象都是由元类对象创建,元类对象自身创建自身。即类本身也是一个对象即类对象。
实例对象在创建时,由Python解释器自动赋予了一个特殊的属性即__class__(可以认为是魔法属性)。该属性的作用是:会找到相对应的实例对象的类对象内存地址。
我们知道我们在定义类时,将所有的实例方法和类方法以及静态方法是定义在类对象中的。那么实例对象是如何访问到实例方法和类方法以及静态方法的呐?这就是__class__属性的作用了,在内存中也确实是这种情况。文字不好描述,直接上图。
在创建实例对象后会自动执行初始化方法(__init(self,*args,**args)),将实例对象的属性进行初始化,并在内存中将实例对象的属性存储在实例对象的线性地址中(有兴趣的化可以去看看数据结构)。这样一来就可以通过实例对象直接访问实例属性。那么还是那个问题,定义类时,将所有的实例方法和类方法以及静态方法是定义在类对象中的。那么实例对象是如何访问到实例方法和类方法以及静态方法的呐?通过上图我们可以看到__class__属性的作用:当实例对象在自己的线性地址中找不到该实例方法时,会通过__class__属性去找到创建该实例对象的类对象,直接访问类对象中线性地址存储的属性和方法。这也就是实例对象可以调用实例方法和类方法以及静态方法及类属性的主要根本原因。
然而可能又有疑问了,为什么类对象不能调用实例方法和实例属性呐?
对于实例属性比较好解释:因为实例对象的属性是存储在实例对象的线性空间里,而类对象的__class__属性只能去找到创建该类对象的类对象的内存地址(可以理解为元类对象的内存地址),所以无法访问实例属性。
对于实例方法哪啊?有人可能会问:“”实例方法不是存储在类对象中吗?为什么类对象不能访问?“”这就要说到关于修饰器,(在这里就不累述修饰器的概念了,我会专门分一片文章去讲解,有兴趣的可以关注一下,我的博客,我会不定期的更新一些文章,分享我的一些经验和体会。)在 类对象中如果要去访问方法时,类对象会找修饰器关键字即@staticmethod或者@classmethod,经修饰器修饰过的方法才能被类对象调用。因此实例方法无法被类对象去调用。
总结:
说到这里,不知道会不会对你的疑惑有所帮助,在这里我做一下简单的总结。
所有的实例对象都必须有父类对象。
所有的实例对象都是由 元类 或者 解释器内置的类对象 以及 自定义的类对象 创建出来。
所有的对象都有__class__属性,是由创建对象时由解释器自动添加的属性。
类属性、实例方法、类方法、静态方法在内存中只保存⼀份。
实例属性在每个实例对象中都要保存⼀份。
实例⽅法:由对象调⽤;⾄少⼀个self参数;执⾏实例⽅法时,⾃动将调
⽤该⽅法的对象赋值给self。
类⽅法:由类调⽤; ⾄少⼀个cls参数;执⾏类⽅法时,⾃动将调⽤该⽅
法的类赋值给cls。
回顾上面图片中的代码,我们可以再去分析看看会不会有新的理解。
相关文章推荐
- python 通过字符串调用对象属性或方法的实例讲解
- 实例详解Java中如何对方法进行调用
- python_如何对实例属性进行类型检查?
- python私有属性和方法实例分析
- 简单理解Python中的类对象、实例对象、属性、方法
- python私有属性和方法实例分析
- C#反射新建类实例和调用类方法及属性帮助类 以及获取或设置对象属性中字段值帮助类
- python中的对象,方法,类,实例,函数用法分析
- python 7-6 如何使用描述符对实例属性做类型检查,分别实现set,方法,在set内使用isinstance做类型检查
- [cnblogs镜像] 只声明对象也能调用方法但不起作用的原因分析
- python如何对实例属性进行类型检查
- 对对象类型和调用方法属性进行存储以提升反射性能
- python_如何通过实例方法名字调用方法?
- python中类和实例如何绑定属性与方法示例详解
- 写一个方法进行各种属性的更新,而不要每个界面设置改变都改变一个属性。就是点击应用或确定按钮时调用这个更新属性的方法,遍历所有(控制对象属性的)界面控件的状态(值),进行属性修改和刷新。
- OC 对象调用属性或实例变量或方法的细节。
- Sql2012如何将远程服务器数据库及表、表结构、表数据导入本地数据库 自定义日志记录功能,按日记录,很方便 C#常量和字段以及各种方法的语法总结 类型,对象,线程栈,托管堆在运行时的关系,以及clr如何调用静态方法,实例方法,和虚方法 asp.net webapi 自定义身份验证
- AS、Flex如何循环调用一个对象的属性、方法
- python如何通过实例方法名字调用方法
- Python中的对象,方法,类,实例,函数用法分析