多态是指通过基类的指针或者引用,在运行时动态调用实际绑定对象函数的行为。

  对于其他如C++的语言,多态是通过在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数。

class A
{
public:
virtual void show()
{
cout <<"A";
}
};
class B:public A
{
public:
void show()
{
cout << "B";
} };
int main()
{
A*p = new B(); //父类指针指向子类对象
p->show();
}

  而在python中,可以这么写

class A:
def say(self):
print('A') class B:
def say(self):
print('B') def say(obj):
obj.say() a = A()
say(a)

  那么,它内部是怎么实现的呢?

  首先,我们先看一下Python源码中的object.h文件的顶部注释

  

  在第一句里面写着,对象总是通过指针PyObject *来访问。那么什么是PyObject呢。

  在Python中,所有的东西都是对象,而PyObject里面是所有对象中所拥有的相同的内容。

  我们来看两个结构体:

typedef struct _object {
_PyObject_HEAD_EXTRA
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
} PyObject; typedef struct {
PyObject ob_base;
Py_ssize_t ob_size; /* Number of items in variable part */
} PyVarObject;

  第一个就是PyObject,而第二个,我们根据名字就可以知道这是可变的对象的结构体,包含了一个PyObject和一个所容纳元素的个数部分。

  当我们创建一个对象时,分配内存进行初始化,这时候会用一个PyObject类型的指针变量来指向这块内存进行保存和维护。

  就像我们声明一个整数,得到整数对象,用于指向这块内存地址的,不是PyIntObject *,而是PyObject *。

  其实类型本身也是一种对象,PyTypeObject。当我们实例化一个整数对象的时候。PyIntObject的ob_type指针指向PyInt_Type,而PyInt_Type的ob_type又指向PyType_Type。而PyInt_Type和PyType_Type其实都是PyTypeObject的示例。

  所以,我们在传递对象的时候,传递的是PyObject *指针这种泛型指针,我们只能通过ob_type进行判断对象类型,通过传递泛型指针的方式,实现了Python的多态。

  

最新文章

  1. Python常用方法
  2. word20161221
  3. (转)SVN服务器搭建和使用(三)
  4. iOS Sonar 集成流程
  5. Hbase总结(一)-hbase命令,hbase安装,与Hive的区别,与传统数据库的区别,Hbase数据模型
  6. RMAN 备份详解
  7. Cocos开发中Visual Studio下HttpClient开发环境设置
  8. python selenium启动浏览器打开百度搜索
  9. 由WSDL文件生成WEB service server端C#程序(转)
  10. enumerate小技巧和列表推导式
  11. 怎么使用CURL传输工具发送get或者post指令
  12. 优雅地 `async/await`
  13. IntelliJ Idea 配置Tomcat提示Port is not specified
  14. ASP.NET Core Cookie-based认证实现
  15. shell循环(两个日期比较,改变某个特定日期来改变当前比较值)
  16. C# 连接数据库实现增删改查
  17. Java中一种无意识的递归
  18. nginx php-fpm 输出php错误日志(转)
  19. Qt界面(控件)相关设计
  20. Java 进阶7 并行优化 JDK多任务执行框架技术

热门文章

  1. iOS不同版本号适配问题(#ifdef __IPHONE_7_0)
  2. Codeforces Round #253 (Div. 1)-A,B
  3. 并查集图冲突hdu1272
  4. 【cl】测试用例【文本框-电子邮箱】
  5. 输入URL 一瞬间发生了什么
  6. To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog]
  7. 适配器模式(adapter)C++实现
  8. Dynamic编程
  9. Android studio 隐藏toolbar上的app title
  10. 9) 十分钟学会android--使用Fragment建立动态UI