Python学习笔记——特殊方法

来源:互联网 发布:数据挖掘和r语言 编辑:程序博客网 时间:2024/06/06 00:54

特殊方法

特点:
特殊方法定义在class内
不需要直接调用
Python的某些函数或操作附会调用对应的特殊方法

__str__和 __repr__

print
python把任意变量变成str,因为任意数据类型的实例都有一个特殊方法 __str__()

__str__()用于显示给用户,而__repr__()用于显示给开发人员。
__repr__的目标是准确性,%r打印时能够重现它所代表的对象
__str__的目标是可读性,%s

import datetime  d = datetime.date.today()  print "%s" % d  print "%r" % d  

2015-12-23
datetime.date(2015, 12, 23)

__cmp__

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

sorted默认由小到大,cmp()
sorted(iterable, cmp=None, key=None, reverse=False)

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

修改 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)    def __cmp__(self,s):        if self.score == s.score:            return cmp(self.name,s.name)        return -cmp(self.score,s.score)L = [Student('Tim',79),Student('Bob',82),Student('Tom',99)]print sorted(L)

__len__

如果一个类表现得像一个list,要获取有多少个元素,就得用 len() 函数。类必须提供一个特殊方法__len__(),它返回元素的个数。
打印斐波那契数列,并返回数列和个数

class Fib(object):    def __init__(self,num):        a,b,L = 0,1,[]        for i in range(10):            L.append(a)            a,b = b,a+b        self.num = L    def __str__(self):        return str(self.num)    __repr__ = __str__    def __len__(self):        return len(self.num)f = Fib(10)print fprint len(f)

数学运算

用于有理数的运算

def gcd(a,b):    if b == 0:        return a    return gcd(b,a%b)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):        g = gcd(self.p,self.q)        return '%s/%s' % (self.p/g,self.q/g)    __repr__ = __str__r1 = Rational(1,2)r2 = Rational(1,4)print r1 + r2print r1 - r2print r1 * r2print r1 / r2

@property

用装饰器(@property)函数把 get/set 方法“装饰”成属性调用
@property—这是关键字,固定格式,能让方法当“属性”用。
@score.setter—前面的”score”是@property紧跟的下面定义的那个方法的名字,”setter”是关键字,这种“@+方法名字+点+setter”是个固定格式与@property搭配使用。

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    @property    def grade(self):        if self.__score < 60:            return 'C'        if self.__score < 80:            return 'B'        return 'A's = Student('Tom',80)print s.grades.score = 62print s.grades.score = 98print s.grade

__slots__

由于Python是动态语言,任何实例在运行期都可以动态地添加属性。
如果要限制添加的属性,例如,Student类只允许添加 name、gender和score 这3个属性,就可以利用Python的一个特殊的__slots__来实现。
顾名思义,__slots__是指一个类允许的属性列表

class Student(object):    __slots__=('name','gender','score')    def __init__(self,name,gender,score):        self.name = name        self.score = score        self.gender = gender

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

__call__

在Python中,函数其实是一个对象.所有的函数都是可调用对象。一个类实例也可以变成一个可调用对象,只需要实现一个特殊方法__call__()。

class Fib(object):    def __call__(self,num):        a,b,L = 0,1,[]        for n in range(num):            L.append(a)            a,b = b,a+b        return Lf = Fib()print f(10)
0 0
原创粉丝点击