python2.2之后,对类和类型做了同意,将int()、float()、str()、list()、touple()这些BIF转换为工厂函数

>>> type(len)
<class 'builtin_function_or_method'>
>>> type(int)
<class 'type'>
>>> type(dir)
<class 'builtin_function_or_method'>
>>> type(list)
<class 'type'>

在来看一个例子

>>> class C():
pass >>> type(C)
<class 'type'>

它的类型是type类型,也是类对象,其实所谓的工厂函数,就是一个类对象,当你调用他们的时候,实际上就是创建一个实例对象:

>>> type(C)
<class 'type'>
>>> a = int('')
>>> b = int('')
>>> a + b
579

由此可以看出,对象是可以计算的。python中无处不对象,当在求a+b等于多少的时候,事实上python就是将两个对象进行相加操作。python的魔法方法还体统了自定义对象的数值处理,通过对下面这些魔法方法的重写,可以自定义任何对象间的算术运算。

1、运算和反运算

         运算                                                      反运算
__add__(self,other):定义加法行为 __radd__(self,other)
__sub__(self,other):减法行为 __rsub__(self,other)
__mul__(self,other):乘法行为 __rmul__(self,other)
__truediv__(self,other):除法行为 __rtruediv__(self,other)
__floordiv__(self,other):整除// __rfloordiv__(self,other)
__mod__(self,other):取模行为% __rmod__(self,other)
__divmod__(self,other):定义当被divmod()调用时行为 __rdivmod__(self,other)
__pow__(self,other):乘方** __rpow__(self,other)
__rshift__(self,other)和__lshift__(self,other):左移位<<和右移位>> __rrshift__(self,other)和__rlshift__(self,other)
__and__(self,other):按位与& __rand__(self,other)
__xor__(self,other):按位或^ __rxor__(self,other)
__or__(self,other):按位或操作的行为 __ror__(self,other)

举个例子

>>> class  New_int(int):
def __add__(self,other):
return int.__sub__(self,other)
def __sub__(self,other):
return int.__add__(self,other) >>> a = New_int(3)
>>> b = New_int(5)
>>> a
3
>>> b
5
>>> a + b
-2
>>> a - b
8

这里用了python默认的方法,如果自己定义了,尝试一下就会发现错误

>>> class  Try_int(int):
def __add__(self,other):
return self + other #出现了无限递归,主要原因在于:对象涉及加法操作,自动调用了魔法方法__add__(),返回return self+other也就是对象本身加另一个对象,形成了无限递归
def __sub__(self,other):
return self - other >>> a = Try_int(1)
>>> b = Try_int(2)
>>> a + b
Traceback (most recent call last):
File "<pyshell#44>", line 1, in <module>
a + b
File "<pyshell#41>", line 3, in __add__
return self + other
File "<pyshell#41>", line 3, in __add__
return self + other
File "<pyshell#41>", line 3, in __add__
return self + other
[Previous line repeated 327 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object

上面例子可以修改下,就不会出现无限递归了

>>> class  Try_int(int):
def __add__(self,other):
return int(self) + int(other)
def __sub__(self,other):
return int(self) - int(other) >>> a = Try_int(1)
>>> b = Try_int(2)
>>> a + b
3

关于反运算我这里举一个例子,

 class Nint(int):
def __radd__(self, other):
return int.__sub__(self,other) c = Nint(5)
d = Nint(3)
print(a+b) #-2

所以在重写反运算魔法方法的时候,一定要注意顺序问题。

2、增量赋值运算

python也有大量的魔法方法可以定制增量赋值语句,增量赋值其实就是一种能偷懒的形式,它将操作符与赋值的形式结合起来,例如

>>> a = a + b #一般形式
>>> a += b #协成增量赋值的形式

3、一元操作符

一元操作符就是只有一个操作数的意思,像a+b这样,加号左右有a.b两个操作数,叫做二元操作符。只有一个操作数的,例如把剑豪放在一个操作数的前边,就是取这个操作数的相反数的意思,这个时候管它叫负号。

python支持的一元操作符主要有__neg__()(表示正号),__pos__()(定义负号),__abs__()(定义当被__abs__()调用时取绝对值的意思),__invert__()(定义按位取反)

python_魔法方法(二):算术运算的更多相关文章

  1. 魔法方法:算术运算 - 零基础入门学习Python042

    魔法方法:算术运算 让编程改变世界 Change the world by program 我现在重新提一个名词:工厂函数,不知道大家还有没有印象?我们在老早前就提到过Ta,由于那时候我们还没有学习类 ...

  2. python_魔法方法(四):属性访问

    通常可以通过点(.)操作符的形式去访问对象的属性,也可以通过BIF适当地去访问属性,看个例子吧 >>> class A(): def __init__(self): self.x = ...

  3. 零基础学习python_魔法方法(41-48课)(迭代器)

    接下来这个为啥要叫魔法方法呢,额,这个嘛我是跟小甲鱼的视频取的名字一样的,因为会讲比较多杂的东西,有... 魔法方法详细阅读地址:http://bbs.fishc.com/thread-48793-1 ...

  4. python_魔法方法(六):迭代器和生成器

    迭代器 自始至终,都有一个概念一直在用,但是我们却没来都没有人在的深入剖析它.这个概念就是迭代. 迭代的意思有点类似循环,每一次的重复的过程被称为迭代的过程,而每一次迭代得到的结果会被用来作为下一次迭 ...

  5. python_魔法方法(五):描述符和定制序列

    描述符(property的原理) 描述符(descripto),用一句话来解释,描述符就是某种特殊的类的实例指派给另一个类的属性.那么什么是特殊类型的类呢?就是至少要在这个类中定义__get__(). ...

  6. python_魔法方法(三):__str__()和__repr__()

    使用python的魔法方法和time模块定制一个计时器的类 1.用time模块里的localtime()方法获取时间2.time.localtime返回struct_time格式3.表现你的类:__s ...

  7. python_魔法方法(一):构造和析构

    魔法方法总是被双下划线包围,例如:__init__() 魔法方法是面向对象的python的一切,它的魔力体现在总能在合适的时候调用. 先来介绍析构和构造的三个魔法方法: __init__():构造方法 ...

  8. python语法学习第十天--魔法方法

    魔法方法二!!! 属性访问:在对属性任何操作时,都会调用   有关属性 __getattr__(self, name) 定义当用户试图获取一个不存在的属性时的行为 __getattribute__(s ...

  9. python_面向对象魔法方法指南

    原文: http://www.rafekettler.com/magicmethods.html 原作者: Rafe Kettler 翻译: hit9 原版(英文版) Repo: https://gi ...

随机推荐

  1. 使用MDI窗体实现多窗口效果

    本文章已收录于:   C#MDI窗体实现多窗口效果   Visual C#是微软公司推出的下一代主流程序开发语言,他也是一种功能十分强大的程 序设计语言,正在受到越来越多的编程人员的喜欢.在Visua ...

  2. 利用dynamic来提供动态方法的性能

    前段时间做了一个worklist的项目,有部分是利用xml配置DICOM的tag,然后根据xml把DICOM的Dataset转为实体类,或者把实体类转为Dataset. 当中主要应用了反射来调用Dat ...

  3. Python-IO模式介绍

    事件驱动模型:有个事件队列,把事件放到队列里,然后循环这个队列,取出事件执行 5种IO模式: 阻塞 I/O(blocking IO) 非阻塞 I/O(nonblocking IO) I/O 多路复用( ...

  4. 使用python对文件夹里面所有代码行数进行统计。

    统计目录下所有的代码个数和总行数. # -*- coding: utf-8 -*- # @Author : ydf import json import os from pathlib import ...

  5. Android M AudioPolicy 分析

    1.AudioPolicyService基础 AudioPolicy在Android系统中主要负责Audio"策略"相关的问题.它和AudioFlinger一起组成了Android ...

  6. Eclipse中插件的使用:maven /ant /tomcat

    一:使用Eclipse构建Maven项目 http://blog.csdn.net/jackgaolei/article/details/11332249 二:Maven介绍,包括作用.核心概念.用法 ...

  7. js验证文本框数字

    输入框 <input name="title" type="text" oninput="onlyNum(this,'')" titl ...

  8. Java有几种引用类型?

    有这样一类对象:当内存空间还足够,则可保留在内存中:如果内存空间在gc之后还是非常紧张,则可抛弃这些对象.很多系统的缓存功能适合这样的场景,所以jdk1.2以后 java将引用分为了强引用.软引用.弱 ...

  9. 【Hadoop】hiveserver2 不能启动端口 10000 开启服务的相关经验总结

    转载来自http://blog.csdn.net/lsttoy/article/details/53490144. 这个问题困扰了我三天,各种查资料踩坑填坑的尝试,终于搞定了这个问题. 首先来品尝下喜 ...

  10. Ubuntu的apt-get本地源搭配——根据需要自己添加软件作源

    试验机器:   Ubuntu 12.04.Lubuntu都可,其他版本应该也没问题,服务器ip:192.168.235.133     主机执行步骤:   1.在/var/cache/apt/arch ...