python 魔法方法
I am not a creator, I just a porter.
Note: Everything is object in python. 对于Python来说一切都是对象,也就是函数的参数可以传递任何你想传递的参数。在Python中整数,浮点都是对象,函数,类也是对象。这一点和Java有点不同,在Java中是有基本类型的所以有装箱拆箱。但在Python中都是对象,所以万物皆对象!
>>> dir(1)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real']
>>> type(1)
<type 'int'>
python对象的特殊方法 ### {#method}
构造方法
- __new__(cls, *args, **kwargs)
__new__ 是对象实例化时第一个调用的方法,它取下cls并把它传递给__init__。注意,在继承的过程中,是先调用父类的__new__在调用本类的__init__。在使用过程中,常用来根据特定的条件来构造类,也是实现单例模式的一个技巧。 - __init__(cls, *args, **kwargs)
__init__是类的初始化方法,可以获取任何传入构造器的参数。 - __del__(cls, *args, **kwargs)
__del__是对象的销毁器。它并非实现了语句del x(因此该语句不等同于 x.__del__()),而是定义了当对象被垃圾回收是的行为。
这是一个简单实现单例模式的例子:
class Singleton(object):
""" 单例模式 """
def __new__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"):
cls._instance = super(cls, Singleton).__new__(cls)
return cls._instance
访问控制
- __getattr__(self, name)
当用户试图访问一个根本不存在(或者暂时不存在)的属性时,可以通过这个魔法方法定义类的行为。这个可以用于使用废弃属性时给出警告。。。。 - __setattr__(self, name, value)
这个是用来定义属性的赋值行为,不管这个属性存在与否,可以对任意的属性的任何变化定义自己的规则,要小心使用。 - ___detattr__(self, name)
这个是用于处理删除属性行为,当我们del self.name时调用,注意防止无限递归。 - __getattribute__(self, name)
这个定义属性(不管存在不存在)被访问时的行为,用于新式类。也容易出现无限递归。产生AttributeError
无限递归的问题:
def __setattr__(self, name. value):
self.name = value
# 因为每次属性幅值都要调用 __setattr__(),所以这里的实现会导致递归
# 这里的调用实际上是 self.__setattr('name', value)。因为这个方法一直
# 在调用自己,因此递归将持续进行,直到程序崩溃
def __setattr__(self, name, value):
self.__dict__[name] = value # 使用 __dict__ 进行赋值
# 定义自定义行为
自定义序列
- __len__(self)
定义内建len()的行为 - __getitem__(self, key)
定义对容器使用self[key]进行读取操作的行为,产生KeyError或TypeError - __setitem__(self, key, value)
定义对容器使用self[key] = value进行赋值的行为,产生KeyError或TypeError - __iter__(self)
用于内建iter(),返回一个可迭代对象 - __next__(self)
python 3才有,python2中是next,迭代访问对象, - __reversed__(self)
定义内建reversed()的行为 - __contains__(self, item)
定义in,not in的行为 - __missing__(self, key)
定义试图访问一个字典中不存在的键时的行为
可调用的方法
- __call__(self, *args, **kwargs)
允许类实例像函数那样被调用
上下文管理器
- __enter__(self)
定义使用with声明创建的语句块最开始应该做什么,它的返回值会赋值给with声明的目标,也就是as之后的东西 - __exit__(self, exception_type, exception_value, traceback)
定义当with声明的语句块执行完毕时,上下文管理器的行为
描述器
当一个类含有 __get__,__set__, __delete__中的一个时,就称它为描述器。
- __get__(self, instance, type)
定义当试图取出描述符的值时的行为。 instance 是拥有者类的实例, type是拥有者类本身。 - __set__(self, instance, value)
定义当描述符的值改变时的行为。 instance 是拥有者类的实例, value 是要赋给描述符的值。 - __delete__(self, instance)
定义当描述符的值被删除时的行为。 instance 是拥有者类的实例
这是property()一个纯Python的等价实现:
class Property(object):
"Emulate PyProperty_Type() in Objects/descrobject.c"
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
self.__doc__ = doc
def __get__(self, obj, objtype=None):
if obj is None:
return self
if self.fget is None:
raise AttributeError, "unreadable attribute"
return self.fget(obj)
def __set__(self, obj, value):
if self.fset is None:
raise AttributeError, "can't set attribute"
self.fset(obj, value)
def __delete__(self, obj):
if self.fdel is None:
raise AttributeError, "can't delete attribute"
self.fdel(obj)
class Cell(object):
def getvalue(self, obj):
"Recalculate cell before returning value"
self.recalc()
return obj._value
value = Property(getvalue)
类的表示
- __str__(self)
定义内建str()的行为 - __repr__(self)
定义内建repr()的行为。str()产生人可读的输出,repr()产生机器可读的输出 - __unicode__(self)
定义内建unicode()的行为 - __format__(self)
用于新式字符串格式化时的行为 - __hash__(self)
用于内建hash()的行为,实现这个方法通常也实现__eq__,使得 a == b意味着hash(a) == hash(b) - __dir__(self)
定义内建dir()的行为 - __nonzero__(self)
定义内建bool()的行为
操作符
- __cmp__(self, other)
定义所以比较操作符的行为,self == other时返回0,self > other时返回正整数,self < other时返回负整数。 - __eq__(self, other)
定义操作符(==)的行为 - __ne__(self, other)
定义操作符(!=)的行为 - __lt__(self, other)
定义操作符(<)的行为 - __gt__(self, other)
定义操作符(>)的行为 - __le__(self, other)
定义操作符(<=)的行为 - __ge__(self, other)
定义操作符(>=)的行为 - __pos__(self)
定义操作符(+)的行为,取正操作:+some_object - __neg__(self)
定义操作符(-)的行为,取负操作:-some_object - __abs__(self)
定义内嵌函数abs()的行为 - __invert__(self)
定义取反操作符(~)的行为 - __round__(self, n)
定义内嵌函数round()的行为,n为近视小数点的位数 - __floor__(self)
定义math.floor()的行为,向下取整 - __ceil__(self)
定义math.ceil()的行为,向上取整 - __add__(self, other)
定义加法操作符(+)的行为 - __sub__(self, other)
定义减法操作符(-)的行为 - __mul__(self, other)
定义乘法操作符(*)的行为 - __floordiv__(self, other)
定义除法操作符(//)的行为 - __div__(self, other)
定义除法操作符(/)的行为 - __mod__(self, other)
定义取宇操作符(%)的行为 - __divmod__(self, other)
定义内建divmod()的行为 - __pow__(self)
定义操作符(**)的行为 - __lshift__(self, other)
定义左移操作符(<<)的行为 - __rshift__(self, other)
定义右移操作符(>>)的行为 - __and__(self, other)
定义按位与操作符(&)的行为 - __or__(self, other)
定义按位或操作符(|)的行为 - __xor__(self, other)
定义按位异或操作符(^)的行为
注1:反射算数运算符,所谓的反射运算只不过是运算符交换了以下位置:self + other变成other + self。反射运算符的定义就是在原运算符的前面加个r,如__add__对应的反射运算符就是__radd__。
注2:增强赋值运算符(+=, -=, ...),定义就是在原运算符前面加一个i,如__add__对应的就是__iadd__。
类型转换
- __int__(self)
实现到int的类型转换 - __long__(self)
实现到long的类型转换 - __float__(self)
实现到float的类型转换 - __complex__(self)
实现到complex的类型转换 - __oct__(self)
实现到八进制数的类型转换 - __hex__(self)
实现到十六进制数的类型转换 - __index__(self)
实现当对象应用于切片表达式时到一个整数的类型转换 - __coerce__(self, other)
实现混合模式算数运算,如果不能进行类型转换,返回None,反之返回一个二元组self和other,这两者都被转换为相同的类型
python 魔法方法的更多相关文章
- Python魔法方法总结及注意事项
1.何为魔法方法: Python中,一定要区分开函数和方法的含义: 1.函数:类外部定义的,跟类没有直接关系的:形式: def func(*argv): 2.方法:class内部定义的函数(对象的方法 ...
- python魔法方法:__getattr__,__setattr__,__getattribute__
python魔法方法:__getattr__,__setattr__,__getattribute__ 难得有时间看看书....静下心来好好的看了看Python..其实他真的没有自己最开始想的那么简单 ...
- python魔法方法大全
1.python魔法方法详解: python魔法方法是可以修改重载的,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而 ...
- python 魔法方法补充(__setattr__,__getattr__,__getattribute__)
python 魔法方法补充 1 getattribute (print(ob.name) -- obj.func())当访问对象的属性或者是方法的时候触发 class F(object): def _ ...
- 1. Python 魔法方法
Python 魔法方法 基础: 如果你想... 所以,你写... Python调用... 初始化一个实例 x = MyClass() x.__init__() 作为一个字符串的"官方&quo ...
- with上下文管理 python魔法方法
with语法在Python里很常见, 主要的利好是使用代码更简洁. 常见的使用场景有: 1. 资源对象的获取与释放. 使用with可以简化try...finally ... 2. 在不修改函数代码的前 ...
- python 魔法方法诠释
什么是Python魔法方法 什么是魔法方法呢?它们在面向对象的Python的处处皆是.它们是一些可以让你对类添加"魔法"的特殊方法. 它们经常是两个下划线包围来命名的(比如 ini ...
- python 魔法方法之:__getitem__ __setitem__ __delitem__
h2 { color: #fff; background-color: #7CCD7C; padding: 3px; margin: 10px 0px } h3 { color: #fff; back ...
- python 魔法方法(学习过程的笔记)
有小伙伴会问,什么是python的魔法方法,python的魔法方法有什么用呢, 它们在面向对象的Python的处处皆是.它们是一些可以让你对类添加"魔法"的特殊方法. 它们经常是两 ...
随机推荐
- Google stuff
Google Pro Tip: Use Back-of-the-envelope-calculations to Choose the Best Design - High Scalability - ...
- 文件I/O(不带缓冲)之open函数
调用open函数可以打开或创建一个文件. #include <fcntl.h> int open( const char *pathname, int oflag, ... /* mode ...
- vb.net中常用键值
可在代码中的任何地方用下列常数代替实际值: 常数 值 描述 vbKeyLButton 0x1 鼠标左键 vbKeyRButton 0x2 鼠标右键 vbKeyCancel 0x3 CANCEL 键 v ...
- Java基础知识强化之多线程笔记02:多线程之 面试题(常问)
1. 多线程有几种实现方案,分别是哪几种 ? 两种. 继承Thread类 实现Runnable接口 扩展一种:实现Callable接口.这个得和线程池结合. 2. 同步有几种方式,分别是什么? ...
- android studio的里的 content_XXX_xml问题
遇到这个问题就是androidStudio的版本问题,androidStudio会出现这个问题是在androidStudio1.4以上版本当遇到这个问题的时候建Activity的时候选择EmptyAc ...
- php使用mysql_query查询超大结果集超内存的解决方法
再使用mysql_query查询超大结果集的时候会出现超出内存限制的致命错误,这是因为mysql_query采用的是查询全部结果然后把结果集全部缓存到内存中的方式. mysql的查询还提供了另外一种查 ...
- PHP之ThinkPHP模板标签操作
Action : $User=M("user"); $list=$User->select(); $this->assign("list ...
- 图像处理函数详解——im2bw
im2bw是基于转换为二值图像的算法,用的是otsu's method. matlab中DIP工具箱函数im2bw使用阈值(threshold)变换法把灰度图像(grayscale image)转换成 ...
- ArrayBlockingQueue和LinkedBlockingQueue分析
JAVA并发包提供三个常用的并发队列实现,分别是:ConcurrentLinkedQueue.LinkedBlockingQueue和ArrayBlockingQueue. Concurren ...
- 【转】adb uninstall卸载apk文件说明
昨天在使用adb卸载程序,结果死活卸载不了.我输入的命令和系统提示如下: [plain] view plaincopy arthur@arthur-laptop:~$ adb uninstall ...