特殊方法的定义:

1.定义在某些class当中

2.不需要直接调用

3.Python的某些函数或者是操作符会调用相应的特殊方法

特殊方法很多,我们只需要编写用到的特殊方法,以及有关联性的特殊方法。

——————————————————————————————————————————

__str__和__repr__方法
如果要把一个类的实例变成 str,就需要实现特殊方法__str__():

>>> class Person(object):
def __init__(self,name,gender):
self.name = name
self.gender =gender
def __str__(self):
return '(Person:%s,%s)'%(self.name,self.gender) >>> p = Person('Bob','male')
>>> print (p)
(Person:Bob,male)

但是当我们输入p的时候我们并不能显示出字符串

>>> p
<__main__.Person object at 0x035FC950>

好像是__str__并没有调用

因为 Python 定义了__str__()__repr__()两种方法,__str__()用于显示给用户,而__repr__()用于显示给开发人员。

有一个偷懒的定义__repr__的方法:

>>> class Person(object):
def __init__(self,name,gender):
self.name = name
self.gender =gender
def __str__(self):
return '(Person:%s,%s)'%(self.name,self.gender)
__repr__ = __str__ >>> p = Person('Bob','Male')
>>> p
(Person:Bob,Male)

这里我们在输入P的时候就不会显示出地址了。

————————————————————————————————————————————————

__cmp__:
对 intstr 等内置数据类型排序时,Python的 sorted() 按照默认的比较函数 cmp 排序,但是,如果对一组 Student 类的实例排序时,就必须提供我们自己的特殊方法 __cmp__():

>>>class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
def __str__(self):
return '(%s: %s)' % (self.name, self.score)
__repr__ = __str__ def __cmp__(self, s):
if self.name < s.name:
return -1
elif self.name > s.name:
return 1
else:
return 0
>>> L = [Student('Tim', 99), Student('Bob', 88), Student('Alice', 77)]
>>> print sorted(L)
[(Alice: 77), (Bob: 88), (Tim: 99)]

这里的是python2.0的写法,但是在python3.0当中,它的写法就不是这样的了。

>>> class Student(object):
def __init__(self,name,score):
self.name = name
self.score = score
def __str__(self):
return '(%s:%s)' % (self.name,self.score)
__repr__ = __str__
def __lt__(self,s):
return self.name < s.name
def __gt__(self,s):
return self.name > s.name
def eg(self,s):
return self.name == s.name >>> L = [Student('Tim',99),Student('Bob',88),Student('Alice',77)]
>>> print (sorted(L))
[(Alice:77), (Bob:88), (Tim:99)]

——————————————————————————————————————————————————

__len__函数

>>> class Student(object):
def __init__(self,*args):
self.names = args
def __len__(self):
return len(self.names) >>> L = Student('Bob','Alice','Tim')
>>> print (len(L))
3

要让 len() 函数工作正常,类必须提供一个特殊方法__len__(),它返回元素的个数。

——————————————————————————————————————————————————

数学运算

Python 提供的基本数据类型 int、float 可以做整数和浮点的四则运算以及乘方等运算。

但是,四则运算不局限于int和float,还可以是有理数、矩阵等。

要表示有理数,可以用一个Rational类来表示:

class Rational(object):
def __init__(self, p, q):
self.p = p
self.q = q def __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):
def mydiv(x,y):
if x<y:
x,y=y,x
while x%y!=0:
x,y=y,x%y
mydiv(x,y)
return y
r=mydiv(self.p,self.q)
return '%s/%s' % (self.p/r,self.q/r) __repr__ = __str__ r1 = Rational(1, 2)
r2 = Rational(1, 4)
print r1 + r2
print r1 - r2
print r1 * r2
print r1 / r2

——————————————————————————————————————————————————

类型转换

为了能够将那个Rational函数变为int,我们可以使用int()

在类里面我们可以使用特殊的函数转化。比如命名‘__int__()’

>>> class Rational(object):
def __init__(self,p,q):
self.p = p
self.q = q
def __int__(self):
return self.p // self.q
def __float__(self):
return self.p * 1.0 /self.q >>> print (float(Rational(7,2)))
3.5
>>> print (float(Rational(1,3)))
0.3333333333333333

__________________________________________________________________________

@property

当我们考虑隐秘性的时候,我们会使用__属性__来保证该属性,不会被外在所访问。

class Student(object):
def __init__(self, name, score):
self.name = name
self.__score = score
def get_score(self):
return self.__score
def set_score(self, score):
if score < 0 or score > 100:
raise ValueError('invalid score')
self.__score = score

但是我们可以使用其他的方法来装饰函数,这样可以节约代码。

>> class Student(object):
def __init__(self,name,score):
self.name = name
self.__score = score
@property
def score(self):
return self.__score
@score.setter
def score(self,score):
if score < 0 or score > 100:
raise ValueError('invalid score')
self.__score = score >>> s = Student('Bob',59)
>>> s.score = 60
>>> print (s.score)
60
>>> s.score = 1000
Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
s.score = 1000
File "<pyshell#13>", line 11, in score
raise ValueError('invalid score')
ValueError: invalid score

第一个score(self)是get方法,用@property装饰,第二个score(self, score)是set方法,用@score.setter装饰,@score.setter是前一个@property装饰后的副产品。

——————————————————————————————————————————————————

__slots__

如果要限制添加的属性,例如,Student类只允许添加 name、genderscore 这3个属性,就可以利用Python的一个特殊的__slots__来实现。

>>> class Student(object):
__slots__ = ('name','gender','score')
def __init__(self,name,gender,score):
self.name = name
self.gender = gender
self.score = score >>> s = Student('Bob','male',59)
>>> s.name = 'Tim'
>>> s.score = 99
>>> s.grade = 'A'
Traceback (most recent call last):
File "<pyshell#14>", line 1, in <module>
s.grade = 'A'
AttributeError: 'Student' object has no attribute 'grade'

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

——————————————————————————————————————————————————————

__call__:

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

>>> class Person(object):
def __init__(self,name,gender):
self.name = name
self.gender = gender
def __call__(self,friend):
print ('My name is %s...' % self.name)
print ('My name is %s...'% friend) >>> p = Person('Bob','male')
>>> p ('Tim')
My name is Bob...
My name is Tim...

这里的就是将P变为了一个可调用对象。

python之特殊方法的更多相关文章

  1. Python测试函数的方法之一

    Python测试函数的方法之一 首先介绍简单的try......except尝试运行的放例如下面的图和代码来简单介绍下: 注释:提醒以下代码环境为2.7.x 请3.x以上的同学们老规矩print(把打 ...

  2. 使用python原生的方法实现发送email

    使用python原生的方法实现发送email import smtplib from email.mime.text import MIMEText from email.mime.multipart ...

  3. Python中sorted()方法

    Python中sorted()方法的用法 1.先说一下iterable,中文意思是迭代器. Python的帮助文档中对iterable的解释是:iteralbe指的是能够一次返回它的一个成员的对象.i ...

  4. python类及其方法

    python类及其方法 一.介绍 在 Python 中,面向对象编程主要有两个主题,就是类和类实例类与实例:类与实例相互关联着:类是对象的定义,而实例是"真正的实物",它存放了类中 ...

  5. Python内置方法的时间复杂度(转)

    原文:http://www.orangecube.net/python-time-complexity 本文翻译自Python Wiki本文基于GPL v2协议,转载请保留此协议. 本页面涵盖了Pyt ...

  6. Python LOGGING使用方法

    Python LOGGING使用方法 1. 简介 使用场景 场景 适合使用的方法 在终端输出程序或脚本的使用方法 print 报告一个事件的发生(例如状态的修改) logging.info()或log ...

  7. [Python]读写文件方法

    http://www.cnblogs.com/lovebread/archive/2009/12/24/1631108.html [Python]读写文件方法 http://www.cnblogs.c ...

  8. 转最简便安装python+selenium-webdriver环境方法

    最简便安装python+selenium-webdriver环境方法 from:http://www.easonhan.info/python/2013/12/07/active-python-ins ...

  9. python字符串replace()方法

    python字符串replace()方法 >>> help(str.replace)Help on method_descriptor:replace(...)    S.repla ...

  10. Python中__init__方法介绍

    本文介绍Python中__init__方法的意义.         __init__方法在类的一个对象被建立时,马上运行.这个方法可以用来对你的对象做一些你希望的 初始化 .注意,这个名称的开始和结尾 ...

随机推荐

  1. Installing StackTach

    为StackTach创建database,默认使用MySql,也可以 在settings.py 文件中配置其他的. create stack db mysql -u root -p mysql> ...

  2. ubuntu上安装nodejs

    目录: 1. nodejs的下载 2. 解压和安装 3. 安装过程中出现过的问题 4. 总结 1. nodejs的下载 我刚开始没有linux系统,于是安装了nodejs的windows版本进行学习. ...

  3. Redis简介 & 与Memcache的区别

    redis 是一个基于内存的高性能key-value数据库.   Reids的特点 Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操 ...

  4. Model compatibility cannot be checked because the database does not contain model metadata. Ensure that IncludeMetadataConvention has been added to the DbModelBuilder conventions

    Model compatibility cannot be checked because the database does not contain model metadata. Ensure t ...

  5. AI探索(一)基础知识储备

    AI的定义 凡是通过机器学习,实现机器替代人力的技术,就是AI.机器学习是什么呢?机器学习是由AI科学家研发的算法模型,通过数据灌输,学习数据中的规律并总结,即模型内自动生成能表达(输入.输出)数据之 ...

  6. 14-THREE.JS 聚光灯

    <!DOCTYPE html> <html> <head> <title></title> <script src="htt ...

  7. 在sql查询中为了提高查询效率,我们常常会采取一些措施对查询语句进行sql优化,下面总结的一些方法,有需要的可以参考参考。

    转载https://www.cnblogs.com/zhang-bo/p/9138151.html 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建 ...

  8. 分布式_理论_05_ 一致性算法 Paxos

    一.前言 二.参考资料 1.分布式理论(五)—— 一致性算法 Paxos 2.分布式理论(五) - 一致性算法Paxos

  9. (转)Linux sort命令

    Linux 的 ‘sort’命令的14个有用的范例(一) 2015-5-2 10:29    评论: 3 收藏: 10 编译自:http://www.tecmint.com/sort-command- ...

  10. java 守护线程整理

    java中finally语句不走的可能存在system.exit(0)与守护线程 线程sleep采用TimeUnit类 设定线程的名字thread.getcurrentThread().setName ...