Python中的__new__与__init__魔术方法理解笔记


Posted in Python onNovember 08, 2014

很喜欢Python这门语言。在看过语法后学习了Django 这个 Web 开发框架。算是对 Python 有些熟悉了。不过对里面很多东西还是不知道,因为用的少。今天学习了两个魔术方法:__new__ 和 __init__。

开攻:

如果对 Python 有所简单了解的话应该知道它包含类这个概念的。语法如下:

class ClassName:

    <statement - 1>:

        .

        .   

        .

    <statement - N>

问题来了。像我们学习的 C# 或是 Java 这些语言中,声明类时,都是有构造函数的。类似下面这样子:

public class ClassName{

    public ClassName(){
    }

}

当然访问修饰符不一定非得 public ,这不是重点就不??铝恕D Python 中的构造函数是怎样的呢?我自己的理解是它是没有构造函数的。只不过在初始化时会调用一些内部的可被改变的方法。比如:__new__ 和 __init__ 。从字面意思理解 __new__ 应该会在 __init__ 之前执行,实际查了资料后确实是如此的。官方文档中关于 __init__ 方法有这样一句话:

Many classes like to create objects with instances customized to a specific initial state. Therefore a class may define a special method named __init__()

意思就是说在创建类时,如果想指定的它的初始状态,那么可以通过定义一个指定名称为 __init__ 的方法去实现这样的功能。这样说来 __new__ 并不是官方推荐的初始化类时要使用的方法。但是 __new__ 却是在 __init__ 之前执行的。官方文档中对 __init__ 介绍的第一句便是:当创建实例时调用 __init__ 方法(Called when the instance is created.),后面又介绍说,如果想调用基类的 __init__方法必须显式的调用,只继承基类在初始化子类时并不会自动调用基类的 __init__ 方法。到此应该算是对 __init__ 方法了解了。

下面我们看一下 __new__ 方法是怎么回事儿。先看一下官方文档:

Called to create a new instance of class cls. __new__() is a static method (special-cased so you need not declare it as such) that takes the class of which an instance was requested as its first argument. The remaining arguments are those passed to the object constructor expression (the call to the class). The return value of __new__() should be the new object instance (usually an instance of cls).
Typical implementations create a new instance of the class by invoking the superclass's __new__() method using super(currentclass, cls).__new__(cls[, ...]) with appropriate arguments and then modifying the newly-created instance as necessary before returning it.
If __new__() returns an instance of cls, then the new instance's __init__() method will be invoked like __init__(self[, ...]), where self is the new instance and the remaining arguments are the same as were passed to __new__().
If __new__() does not return an instance of cls, then the new instance's __init__() method will not be invoked.
__new__() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also commonly overridden in custom metaclasses in order to customize class creation.

从这里可以看出来,这个方法才是产生类的实例的地方。当实例创建完成就调用 __init__ 方法,初始化类的内部状态值。文档中还提到 __new__ 方法其实是一个静态方法,不用每次定义类的时候都声明这个方法,因为在版本 2.4 之后 object 是所有对象的基类,而 __new__ 是定义在 object 对象内部的静态方法。

到这儿其实就差不多了,就按字面意思理解就可以。 __new__ 用于创建对象,而 __init__ 是在创建完成之后初始化对象状态。前两天看到一个有趣的方法,通过使用 __new__ 应用了单例模式在对象身上。

注意点:在类继承中,当子类和父类都定义了自己的 __new__ 方法时,那么会先调用子类的 __new__ 方法再调用父类的。这一点倒是和 C# 中的继承是一样的。其实仔细想想 Python 中只不过是把初始化和创建对象这两个概念分开了,而 C# 中即没有这么干,只给了构造函数,开发者可以自己看着办。从这一点儿上说我觉得 Python 的做法我更喜欢。

结束:

今天算是又学习到了新知识,自己挺开心的。再实践实践。。。

Python 相关文章推荐
使用Python的Twisted框架编写简单的网络客户端
Apr 16 Python
Python选课系统开发程序
Sep 02 Python
Python 3.x基于Xml数据的Http请求方法
Dec 28 Python
Django将默认的SQLite更换为MySQL的实现
Nov 18 Python
Python 实现递归法解决迷宫问题的示例代码
Jan 12 Python
使用python3 实现插入数据到mysql
Mar 02 Python
学习Python列表的基础知识汇总
Mar 10 Python
django执行原始查询sql,并返回Dict字典例子
Apr 01 Python
基于python实现检索标记敏感词并输出
May 07 Python
python3.7+selenium模拟淘宝登录功能的实现
May 26 Python
numpy中生成随机数的几种常用函数(小结)
Aug 18 Python
如何使用Python提取Chrome浏览器保存的密码
Jun 09 Python
Python使用百度API上传文件到百度网盘代码分享
Nov 08 #Python
python中readline判断文件读取结束的方法
Nov 08 #Python
Python实现基于HTTP文件传输实例
Nov 08 #Python
Python使用urllib模块的urlopen超时问题解决方法
Nov 08 #Python
Python set集合类型操作总结
Nov 07 #Python
数据挖掘之Apriori算法详解和Python实现代码分享
Nov 07 #Python
Python的subprocess模块总结
Nov 07 #Python
You might like
用Flash图形化数据(二)
2006/10/09 PHP
ThinkPHP3.1新特性之动态设置自动完成及自动验证示例代码
2014/06/23 PHP
php中常量DIRECTORY_SEPARATOR用法深入分析
2014/11/14 PHP
PHP的serialize序列化数据以及JSON格式化数据分析
2015/10/10 PHP
PHP创建单例后台进程的方法示例
2017/05/23 PHP
Referer原理与图片防盗链实现方法详解
2019/07/03 PHP
JavaScript弹簧振子超简洁版 完全符合能量守恒,胡克定理
2009/10/25 Javascript
JavaScript类和继承 this属性使用说明
2010/09/03 Javascript
JS无限树状列表实现代码
2011/01/11 Javascript
JQuery中如何传递参数如click(),change()等具体实现
2013/04/28 Javascript
JS实现关键字搜索时的相关下拉字段效果
2014/08/05 Javascript
jQuery中even选择器的定义和用法
2014/12/23 Javascript
原生js实现数字字母混合验证码的简单实例
2015/12/10 Javascript
node.js平台下的mysql数据库配置及连接
2017/03/31 Javascript
微信小程序之页面跳转和参数传递的实现
2017/09/29 Javascript
node版本管理工具n包使用教程详解
2018/11/09 Javascript
[01:56]2014DOTA2西雅图邀请赛 MVP外卡赛老队长精辟点评
2014/07/09 DOTA
python中dir()与__dict__属性的区别浅析
2018/12/10 Python
12个Python程序员面试必备问题与答案(小结)
2019/06/24 Python
django中使用事务及接入支付宝支付功能
2019/09/15 Python
python统计文章中单词出现次数实例
2020/02/27 Python
Python并发concurrent.futures和asyncio实例
2020/05/04 Python
如何基于Python代码实现高精度免费OCR工具
2020/06/18 Python
Python读取二进制文件代码方法解析
2020/06/22 Python
Python使用Selenium模拟浏览器自动操作功能
2020/09/08 Python
python输出国际象棋棋盘的实例分享
2020/11/26 Python
CSS3等相关属性制作分页导航实现代码
2012/12/24 HTML / CSS
Html5内唤醒百度、高德APP的实现示例
2019/05/20 HTML / CSS
YOOX台湾:意大利奢侈品电商
2018/10/13 全球购物
现代生活方式的家具和装饰:Dot & Bo
2018/12/26 全球购物
屈臣氏官方旗舰店:亚洲享负盛名的保健及美妆零售商
2019/03/15 全球购物
ORACLE第二个十问
2013/12/14 面试题
2014年连锁店圣诞节活动方案
2014/12/09 职场文书
2015年事业单位工作总结
2015/04/27 职场文书
python xlwt模块的使用解析
2021/04/13 Python
python读取并查看npz/npy文件数据以及数据显示方法
2022/04/14 Python