python中__init__后面加特殊符号_详解Python中的__new__、__init__、__call__三个特殊方法...
__new__: 对象的创建,是一个静态方法,第一个参数是cls。(想想也是,不可能是self,对象还没创建,哪来的self)
__init__ : 对象的初始化, 是一个实例方法,第一个参数是self。
__call__ : 对象可call,注意不是类,是对象。
先有创建,才有初始化。即先__new__,而后__init__。
上面说的不好理解,看例子。
1.对于__new__
class Bar(object):
pass
class Foo(object):
def __new__(cls, *args, **kwargs):
return Bar()
print Foo()
可以看到,输出来是一个Bar对象。
__new__方法在类定义中不是必须写的,如果没定义,默认会调用object.__new__去创建一个对象。如果定义了,就是override,可以custom创建对象的行为。
聪明的读者可能想到,既然__new__可以custom对象的创建,那我在这里做一下手脚,每次创建对象都返回同一个,那不就是单例模式了吗?没错,就是这样。可以观摩《飘逸的python - 单例模式乱弹》
定义单例模式时,因为自定义的__new__重载了父类的__new__,所以要自己显式调用父类的__new__,即object.__new__(cls, *args, **kwargs),或者用super()。,不然就不是extend原来的实例了,而是替换原来的实例。
2.对于__init__
使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候。例如:
# -*- coding: utf-8 -*-
class Person(object):
"""Silly Person"""
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return '' % (self.name, self.age)
if __name__ == '__main__':
piglei = Person('piglei', 24)
print piglei
这样便是__init__最普通的用法了。但__init__其实不是实例化一个类的时候第一个被调用 的方法。当使用 Persion(name, age) 这样的表达式来实例化一个类时,最先被调用的方法 其实是 __new__ 方法。
3.对于__call__对象通过提供__call__(slef, [,*args [,**kwargs]])方法可以模拟函数的行为,如果一个对象x提供了该方法,就可以像函数一样使用它,也就是说x(arg1, arg2...) 等同于调用x.__call__(self, arg1, arg2) 。模拟函数的对象可以用于创建防函数(functor) 或代理(proxy).
class Foo(object):
def __call__(self):
pass
f = Foo()#类Foo可call
f()#对象f可call
总结,在Python中,类的行为就是这样,__new__、__init__、__call__等方法不是必须写的,会默认调用,如果自己定义了,就是override,可以custom。既然override了,通常也会显式调用进行补偿以达到extend的目的。
这也是为什么会出现"明明定义def _init__(self, *args, **kwargs),对象怎么不进行初始化"这种看起来诡异的行为。(注,这里_init__少写了个下划线,因为__init__不是必须写的,所以这里不会报错,而是当做一个新的方法_init__)
python中__init__后面加特殊符号_详解Python中的__new__、__init__、__call__三个特殊方法...相关推荐
- python函数中可变参数的传递方式是_详解Python函数可变参数定义及其参数传递方式...
Python函数可变参数定义及其参数传递方式详解 python中 函数不定参数的定义形式如下 1. func(*args) 传入的参数为以元组形式存在args中,如: def func(*args): ...
- python的装饰器迭代器与生成器_详解python中的生成器、迭代器、闭包、装饰器
迭代是访问集合元素的一种方式.迭代器是一个可以记住遍历的位置的对象.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退. 1|1可迭代对象 以直接作用于 for ...
- python中heapq的库是什么_详解Python中heapq模块的用法
详解Python中heapq模块的用法 来源:中文源码网 浏览: 次 日期:2018年9月2日 [下载文档: 详解Python中heapq模块的用法.txt ] (友情提示:右键点上行t ...
- python中get函数是什么意思_详解python中get函数的用法(附代码)_后端开发
strncmp函数用法详解_后端开发 strncmp函数为字符串比较函数,其函数语法为"int strncmp ( const char * str1, const char * str2, ...
- python中groupby()函数讲解与示例_详解python中groupby函数通俗易懂
一.groupby 能做什么? python中groupby函数主要的作用是进行数据的分组以及分组后地组内运算! 对于数据的分组和分组运算主要是指groupby函数的应用,具体函数的规则如下: df[ ...
- python比较两个字符串相似度_详解Python 字符串相似性的几种度量方法
字符串的相似性比较应用场合很多,像拼写纠错.文本去重.上下文相似性等. 评价字符串相似度最常见的办法就是:把一个字符串通过插入.删除或替换这样的编辑操作,变成另外一个字符串,所需要的最少编辑次数,这种 ...
- java中的静态变量的作用域_详解JAVA中static的作用
1.深度总结 引用一位网友的话,说的非常好,如果别人问你static的作用:如果你说静态修饰 类的属性 和 类的方法 别人认为你是合格的:如果是说 可以构成 静态代码块,那别人认为你还可以: 如果你说 ...
- python怎么打下划线符号_详解 Python 中的下划线命名规则
在 python 中,下划线命名规则往往令初学者相当 疑惑:单下划线.双下划线.双下划线还分前后--那它们的作用与使用场景 到底有何区别呢?今天 就来聊聊这个话题. 1.单下划线(_) 通常情况下,单 ...
- python中ifelifelse用在什么结构_详解Python if-elif-else知识点
有的时候,一个 if - else - 还不够用.比如,根据年龄的划分:条件1:18岁或以上:adult 条件2:6岁或以上:teenager 条件3:6岁以下:kid Python if-elif- ...
最新文章
- xshell / xftp家庭/学校免费版官网下载地址
- PlentyOfFish.com .NET网站的又一传奇
- c mvc ajax 返回下拉框,SpringMVC之ajax+select下拉框交互常用方式
- 一半的一半(51Nod-2382)
- python2 字符串函数_笔记六:python2字符串运算与函数
- 熬夜总结学了一半的JDBC
- Spring容器启动后注入service到Servlet并自动执行
- [翻译]Web开发牛人访谈:你们都在用什么?
- 汽车故障诊断技术【1】
- matlab风玫瑰图,风玫瑰图的Matlab编程绘制
- 如何防止别人QQ群话题发广告和批量QQ群发Q群话题
- CodeForces - 884B Japanese Crosswords Strike Back
- 汽车距离报警系统c语言编程,基于单片机的汽车防盗报警系统设计与实现.doc
- linux 硬盘品牌,CentOS如何查看硬盘品牌型号等具体信息
- CSS 渐变背景 之 线性渐变
- Python笔记 No.1 - Python函数及装饰器
- 计算机设备配备情况,计算机设备配置标准.doc
- 理论力学知识要点归纳(四)
- 中国科学院计算机所张浩,航天科技集团调研组到计算所交流
- 麦克斯韦方程组的组成由来、媒介的电磁性质和边界条件
热门文章
- 网盘纷退场 “云存储”仍是刚需
- OpenStack icehouse系列之计算节点搭建
- HDR 拍照模式的原理,实现及应用
- Java中书写要注意的地方
- ASP.NET MVC 向浏览器发送文件以提供文件下载功能
- 802.11n 原理解析
- 为什么要进行傅立叶变换?傅立叶变换究竟有何意义?如何用Matlab实现快速傅立叶变换?
- github如何clone别人commit的历史版本的仓库
- CSP认证201712-1	最小差值[C++题解]:遍历
- CSP认证201609-2	火车购票[C++题解]:模拟、vector、排序