Python中的特殊方法

Python的特殊方法定义在 class中,不需要直接进行显示调用,Python的某些操作符或者函数会自动调用对应的特殊方法。这些方法如:__str__()__len__()__cmp__()等。下面这些更全面:

正确实现特殊方法:首先只需要编写用到的特殊方法;其次有关联性的特殊方法必须都实现,如编写了特殊方法 __getattr__(),那么特殊方法 __setattr__()__delattr__()也必须实现。

__str____repr__方法:

先来看代码示例:

class Person(object):def __init__(self, name, gender):self.name = nameself.gender = genderclass Student(Person):def __init__(self, name, gender, score):super(Student, self).__init__(name, gender)self.score = scoredef __str__(self):return '(Student: %s, %s, %s)' % (self.name, self.gender, self.score)__repr__ = __str__s = Student('Bob', 'male', 88)
print s            # 输出结果为:(Student: Bob, male, 88)

__str__()方法用来把一个类变成一个字符串输出,在 class中定义该方法,可以使类按照我们想要的格式进行输出。__str__()用于显示给用户,而__repr__()用于显示给开发人员。

__cmp__()方法:

还是先看示例

class Student(object):def __init__(self, name, score):self.name = nameself.score = scoredef __str__(self):return '(%s: %s)' % (self.name, self.score)__repr__ = __str__def __cmp__(self, s):         # 定义__cmp__()方法if self.name < s.name:    # 比较规则(和默认比较规则相同)return -1elif self.name > s.name:return 1else:return 0

上述 Student 类实现了__cmp__()方法,__cmp__用实例自身 self和传入的实例 s 进行比较,如果 self 应该排在前面,就返回 -1,如果 s 应该排在前面,就返回1,如果两者相当,返回 0。
比较结果

L = [Student('Tim', 99), Student('Bob', 88), Student('Alice', 77)]
print sorted(L)   # [(Alice: 77), (Bob: 88), (Tim: 99)]  按照姓名排序

升级版本:先判断类型,然后按照分数排序,分数相同按照姓名排序。如下:

class Student(object):def __init__(self, name, score):self.name = nameself.score = scoredef __str__(self):return '(%s: %s)' % (self.name, self.score)__repr__ = __str__def __cmp__(self, s):if not isinstance(s, Student):return -1else:return -cmp(self.score, s.score) or cmp(self.name, s.name)L = [Student('Tim', 99), Student('Bob', 88), Student('Alice', 99)]
print sorted(L)      # 结果为:[(Alice: 99), (Tim: 99), (Bob: 88)]

注意:在 Python3.4.3版本之后,已经没有cmp() 函数了。被 operator模块中的一系列函数取代,并且使用时需要导入,如下:

import operatora, b = 'Hello', 'name'
operator.lt(a, b)       # 小于比较
operator.le(a, b)       # 小于等于比较
operator.eq(a, b)       # 等于比较
operator.ne(a, b)       # 不等于比较
operator.gt(a, b)       # 大于比较
operator.ge(a, b)       # 大于等于比较# 可在类中编写的内置函数如下:
operator.__lt__(a, b)       # 小于比较
operator.__le__(a, b)       # 小于等于比较
operator.__eq__(a, b)       # 等于比较
operator.__ne__(a, b)       # 不等于比较
operator.__gt__(a, b)       # 大于比较
operator.__ge__(a, b)       # 大于等于比较

__len__()函数:

如果一个类表现得像一个list,要获取有多少个元素,就得用 len() 函数。要让 len() 函数工作正常,类必须提供一个特殊方法__len__(),它返回元素的个数。代码示例如下:

class Fib(object):def __init__(self, num):a, b, l= 0, 1, []for item in range(int(num)):l.append(a)a, b = b, a+bself.nums = ldef __len__(self):return len(self.nums)def __str__(self):return str(self.nums)f = Fib(10)
print f          # 输出结果为:[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
print len(f)     # 输出结果为:10

Python 中的数学运算

Python 提供的基本数据类型 int、float 可以做整数和浮点的四则运算以及乘方等运算。但是,四则运算不局限于int和float,还可以是有理数、矩阵等

通过定制类,计算有理数(分数形式)的加减乘除四则运算。分别编写__add__()__sub__()__mul__()__div__()函数。代码示例如下:

def gcd(a, b):return gcd(b, a%b) if b!=0 else aclass Rational(object):def __init__(self, p, q):self.p = pself.q = qdef __add__(self, r):return Rational(self.p * r.q + self.q * r.p, self.q * r.q)def __sub__(self, r):return Rational(self.p * r.q - self.q * r.p, self.q * r.q)def __mul__(self, r):return Rational(self.p * r.p, self.q * r.q)def __div__(self, r):return Rational(self.p * r.q, self.q * r.p)def __str__(self):temp = gcd(self.p, self.q)return '%s/%s' % (self.p/temp, self.q/temp)__repr__ = __str__r1 = Rational(1, 2)
r2 = Rational(1, 4)
print r1 + r2         # 3/4
print r1 - r2         # 1/4
print r1 * r2         # 1/8
print r1 / r2         # 2/1

Python中的类型转换

Rational类实现了有理数运算,还可以实现int()float()类型转换,示例如下:

class Rational(object):def __init__(self, p, q):self.p = pself.q = qdef __int__(self):return self.p // self.qdef __float__(self):return self.p*1.0 / self.qprint float(Rational(7, 2))    # 3.5
print int(Rational(1, 3))      # 0

Python中@property运用:

Python支持高阶函数,在函数式编程中我们介绍了装饰器函数,可以用装饰器函数把设置和获取属性的 get/set 方法“装饰”成属性调用:

class Student(object):def __init__(self, name, score):self.name = nameself.__score = score@property def score(self):            # 实现 get()方法return self.__score@score.setterdef score(self, score):     # 实现 set()方法if score < 0 or score > 100:raise ValueError('invalid score')self.__score = score@propertydef grade(self):            # 实现 grade属性的 get()方法if self.__score < 60: return 'C'elif self.__score <80: return 'B'else: return 'A's = Student('Bob', 59)
print s.grade               # 输出为:Cs.score = 99                # 输出为:A
print s.grades = Student('Bob', 59)
s.score = 60
print s.score      # 60
s.score = 1000
"""
Traceback (most recent call last):...
ValueError: invalid score
"""

Python中限制属性函数__slots__():

__slots__是指一个类允许的属性列表,它的目的是限制当前类所能拥有的属性,如果不需要添加任意动态的属性,使用__slots__也能节省内存。

class Person(object):__slots__ = ('name', 'gender')def __init__(self, name, gender):self.name = nameself.gender = genderclass Student(Person):__slots__ = ('score')         # 实际上允许的属性还有从父类继承来的 'name' 和 'gender'def __init__(self, name, gender, score):super(Student, self).__init__(name, gender)self.score = scores = Student('Bob', 'male', 59)
s.name = 'Tim'
s.score = 99
print s.score   # 99

Python中对类调用函数__call__():

在Python中,函数其实是一个对象,所有的函数都是可调用对象。

一个类实例也可以变成一个可调用对象,只需要实现一个特殊方法__call__()

class Fib(object):def __call__(self, num):a, b, l= 0, 1, []for item in range(int(num)):l.append(a)a, b = b, a+breturn lf = Fib()       # 获取类对象
print f(10)     # 像调用函数一样,调用类

Python 中的特殊方法(定制类):__str__、__cmp__、__len__、数学运算、类型转换、@property运用、__slots__和__call__函数相关推荐

  1. Python的类和对象的介绍,定义类和对象,定义实例方法和属性以及Python中的魔法方法

    Day09新手小白学python 第九节 Python的类和对象的介绍,定义类和对象,定义实例方法和属性以及Python中的魔法方法 目录 Day09新手小白学python 前言 一.面向对象介绍 二 ...

  2. python深度讲解_《深度剖析CPython解释器》21. Python类机制的深度解析(第五部分): 全方位介绍Python中的魔法方法,一网打尽...

    楔子 下面我们来看一下Python中的魔法方法,我们知道Python将操作符都抽象成了一个魔法方法(magic method),实例对象进行操作时,实际上会调用魔法方法.也正因为如此,numpy才得以 ...

  3. python中的魔方方法

    python中的魔方方法 魔法方法 含义 基本的魔法方法 new(cls[, -]) 1. new 是在一个对象实例化的时候所调用的第一个方法 2. 它的第一个参数是这个类,其他的参数是用来直接传递给 ...

  4. python方法测试怀孕_在Python中测试私有方法(例外)

    在阅读了关于在Python中测试私有方法的内容之后,特别是在How do I unit test the methods in a method object?处引用了接受的答案,看来最好只测试公共接 ...

  5. python方法_详细解读Python中的__init__()方法

    __init__()方法意义重大的原因有两个.第一个原因是在对象生命周期中初始化是最重要的一步:每个对象必须正确初始化后才能正常工作.第二个原因是__init__()参数值可以有多种形式. 因为有很多 ...

  6. python导入类有红线_解决Python中导入自己写的类,被划红线,但不影响执行的问题...

    1. 错误描述 之前在学习Python的过程中,导入自己写的包文件时,与之相关的方法等都会被划红线,但并不影响代码执行,如图: 看着红线确实有点强迫症,并且在这个过程当时,当使用该文件里的方法时不会自 ...

  7. python中pylint使用方法(pylint代码检查)

    一.Pylint 是什么 Pylint 是一个 Python 代码分析工具,它分析 Python 代码中的错误,查找不符合代码风格标准和有潜在问题的代码. Pylint 是一个 Python 工具,除 ...

  8. python使用方法-在Python中使用next()方法操作文件的教程

    next()方法当一个文件被用作迭代器,典型例子是在一个循环中被使用,next()方法被反复调用.此方法返回下一个输入行,或引发StopIteration异常EOF时被命中. 与其它文件的方法,如Re ...

  9. python中range 10 0_如何在python中使用range方法

    如何在python中使用range方法 发布时间:2021-01-05 16:55:23 来源:亿速云 阅读:94 作者:Leah 如何在python中使用range方法?很多新手对此不是很清楚,为了 ...

最新文章

  1. java中的分层概念_Java分层概念
  2. java web svn_如何搭建svnadmin,一个简单的svnWEB页面
  3. 【java】CGLIB动态代理原理分析
  4. python module
  5. EF Core 的Startup配置自动创建数据库
  6. Python字符串endswith()
  7. 海康4200门禁导入人脸_刷脸开门,海康智脑NVR无感开门方案来啦~
  8. 【linux】两个线程实现出库与入库操作
  9. 78 ----二次曲面方程的化简、移轴变换、转轴变换、伸缩变换
  10. 解决0RA-04031故障
  11. VS2010入门教程
  12. allshare cast安卓版下载_PanDownload 安卓手机版,解决百度网盘下载速度慢
  13. opencv部署onnx,并对jpg图片进行批量检测生成xml重要信息
  14. DEDE源码分析与学习---index.php文件解读。
  15. Scipy总结(constants)
  16. QCon 北京 2021:Pulsar PMC 成员翟佳出席并演讲
  17. 从理论到实战,带你全面解读智能物联网技术
  18. android 11中置入第三方应用apk
  19. SpringBoot OA自动化办公系统
  20. java 算数表达式 转成 二叉树,将算术表达式((a+b)+c*(d+e)+f)*(g+h)转化为二叉树。...

热门文章

  1. 机器学习(二)——广义线性模型、生成学习算法
  2. a标签传值到另一个页面_前端开发入门——HTML基础标签
  3. java的比较器_java两种比较器总结
  4. 【c++进阶:c++ 顺序容器vector,string,deque,list,forward_list,array常用性质】
  5. 记录使用websocket时因为Sec-Websocket-Protocol遇到的一个问题
  6. 【Maven】CentOS7使用Nexus3搭建maven私服
  7. Windows 计划任务功能设置闹钟~
  8. POJ 3225 线段树+lazy标记
  9. 无线路由器参数设置精通技巧
  10. Struts1.2+Spring2.5+Hibernate3.2框架搭建(十五)