整理自小甲鱼鱼C论坛
算数运算
Python 2.2以后,对类和类型进行了统一,做法就是将int(), float(), str(), list(), tuple()这些BIF转换为工厂函数:
type(len) |
这与一般的类相同:
class C: |
type类型也就是类对象,所谓的工厂函数就是一个类对象。当调用它们的时候,事实上就是创建一个相应的实例对象,并且类对象本身可以用于运算
a = int('123') |
常见的算数运算相关的魔法方法:
| 魔法方法 | 含义 |
|---|---|
| __add__(self, other) | 定义加法的行为:+ |
| __sub__(self, other) | 定义减法的行为:- |
| __mul__(self, other) | 定义乘法的行为:* |
| __truediv__(self, other) | 定义真除法行为:/ |
| __floordiv__(self,ohter) | 定义整数除法行为:// |
| __mod__(self, other) | 定义取模算法的行为:% |
| __divmod__(self, other) | 定义当被divmod()调用时的行为 |
| __pow__(self, other[,modulo]) | 定义当贝power()调用或**运算时的行为 |
| 以下为汇编行为: | |
| __lshift__(self, other) | 定义按位左移位的行为:<< |
| __rshift__(self, other) | 定义按位右移位的行为:>> |
| __and__(self, other) | 定义按位与操作的行为:& |
| __xor__(self, other) | 定义按位异或操作的行为:^ |
| __or__(self, other) | 定义按位或操作的行为:| |
具体用法,如编程一个新的New_int类,使得加法与减法运算结果相反:
class New_int(int): |
下面观察下面代码的问题出在哪里?
class Try_int(int): |
在我们在通过对Try_intA()进行实例化以后,执行a + b时,读到a +时开始执行__add__()函数,返回self +即a +而后再次执行__add__()函数,继而陷入无限递归。
我们可以通过将返回值强制修改为数值运算,就可以避免这个问题:
class Try_int(int): |
这样在执行a + b时,读到a +执行__add__()函数,返回a的值与b的值的和,这样,即使再次调用__add__()函数,由于缺少实例对象而就不会再次进入递归。
有一点值得注意,看一下代码有什么问题,
class Foo: |
问题在于,在__init__()方法里,如果类中方法名和属性同名,属性会覆盖方法,所以在调用实例对象foo的foo函数时,由于foo函数被属性self.foo = 'Result'所替代,所以会出现TypeError说字符串类型无法被调用。
鸭子类型( duck typing )
鸭子类型是一种动态类型的一种风格,这种风格中,一个对象有效的语义,不是由继承特定的类或实现特定的接口,而是由当前方法和属性的集合决定。
这个名字的由来源自于 James Whitcomb Riley提出的鸭子测试:
当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称作鸭子。
鸭子类型应避免使用type()或者isinstance()等测试类型是否合法。
如下代码,
class Duck: |
location()函数中对参数duck只有一个要求:就是可以实现quack()和feathers()方法,然而Duck类型和Person类都实现了quack()和feathers()的方法,因此donald和john都可以作为location()的参数。
鸭子类型给予了Python这样的动态语言以多态,但是这种多态的实现完全由程序员来约束强制实现,并没有语言上的约束。因此这种方法既灵活,由提高了要求。
又如,
def calc(a, b, c): |
问题:
(1) 定义一个Nstr类,支持字符串的相间操作:A - B,从A中去除所有B的子字符串。
a = Nstr('ABC') |
class Nstr(str): |
replace 函数
描述
Python replace() 方法把字符串中的 old(旧字符串) 替换成 new(新字符串),如果指定第三个参数max,则替换不超过 max 次。
语法
replace()方法语法:
stR.replace(old, new[, max]) |
参数
old – 将被替换的子字符串。
new – 新字符串,用于替换old子字符串。
max – 可选字符串, 替换不超过 max 次
返回值
返回字符串中的 old(旧字符串) 替换成 new(新字符串)后生成的新字符串,如果指定第三个参数max,则替换不超过 max 次。
(2) 移位操作符是应用于二进制操作数的,现在需要你定义一个新的类Nstr,也支持移位操作符的运算:
如下:
a = Nstr('ABCDEFGHK') |
利用__lshift__()函数以及__rshift__()函数
class Nstr(str): |
(3) 定义一个类 Nstr, 当该类的实例对象间发生的加、减、乘、除运算时,将该对象的所有字符串的ASCII码之和进行计算:
如下,
a = Nstr('FishC') |
代码如下:
class Nstr: |
代码的前半部分可以这样改写:
class Nstr(int): |