error: tro 其中 attr_ light b-s 进行 trac
定义在 class 中
不需要直接调用,python 的某些函数或操作符会自动的调用对应的特殊方法。
如定义了 person 类,使用 print p 语句打印 person 类的实例时,就调用了特殊方法__str__()
此时就需要在 person 类中实现这个方法。
使用特殊方法时注意:
只需要编写用到的特殊方法
有关联性的特殊方法都必须实现(如__getattr__,__setattr__,delattr__)
__str__() 用于显示给用户,而__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__ #直接让repr和str相同
定义了 repr 函数后,在调试时直接向命令行输入 p 即可输出 person 的信息,否则会输出
<__main__.Person object at 0x0000000002E66C88>
__str__和__repr__函数会被子类继承。
为了对对象进行排序,可以使用函数 sorted 函数,前提是设置了类的__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)]
调用 len() 返回实例的长度.
- class Students(object):
- def __init__(self, *args):
- self.names = args
- def __len__(self):
- return len(self.names)
- >>> ss = Students('Bob', 'Alice', 'Tim')
- >>> print len(ss)
- 3
- 任务:
斐波那契数列是由 0, 1, 1, 2, 3, 5, 8... 构成。
请编写一个 Fib 类,Fib(10) 表示数列的前 10 个元素,print Fib(10) 可以打印出数列的前 10 个元素,len(Fib(10)) 可以正确返回数列的个数 10。
代码 1:(参考代码)
可以使用 str() 将整型列表转化为字符串。
class Fib(object): def __init__(self, num): a, b, L = 0, 1, [] for n in range(num): L.append(a) a, b = b, a + b self.numbers = L def __str__(self): return str(self.numbers) __repr__ = __str__ def __len__(self): return len(self.numbers) f = Fib(10) print f print len(f)
代码 2:(自己写的)
- class Fib(object):
- def __init__(self, num):
- self.num = num
- def __str__(self):
- if(self.num==1):
- return "[0]"
- elif(self.num==2):
- return "[0,1]"
- else:
- fib_str = "[0,"
- fib=[0,1]
- for k in range(2,self.num+1):
- fib_str = fib_str+ str(fib[k-1]) + ","
- fib.append(fib[k-1]+fib[k-2])
- return fib_str[:-1]+']'
- def __len__(self):
- return self.num
- f = Fib(10)
- print f
- print len(f)
例:有理数可以用 p/q 表示,其中 p 和 q 都是整数。
调用求最大公约数的 gcd 函数(递归):
欧几里得定理:若 a=b*r+q,则 GCD(a,b)=GCD(b,q)
- 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-r.p*self.q,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 + r2
- print r1 - r2
- print r1 * r2
- print r1 / r2
- __int__ 和 __float__方法实现类型转换,
- __str__ 方法也可以看做是一种类型转换。
- 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 float(self.p)/float(self.q)
- print float(Rational(7, 2))
- print float(Rational(1, 3))
@property 修饰方法后即是 get 方法。
"@[email protected]�用,set 方法。
如果没有定义 set 方法,就不能对 "属性" 赋值,这时,就可以创建一个只读 "属性"。
- 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
__slots__规定了一个类允许的属性列表。不允许添加列表外的属性。
- class Student(object):
- __slots__ = ('name', 'gender', 'score')
- def __init__(self, name, gender, score):
- self.name = name
- self.gender = gender
- self.score = score
- 强行添加grade属性会报错。
- >>> s = Student('Bob', 'male', 59)
- >>> s.name = 'Tim' # OK
- >>> s.score = 99 # OK
- >>> s.grade = 'A'
- Traceback (most recent call last):
- ...
- AttributeError: 'Student' object has no attribute 'grade'
- 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 friend is %s...' % friend
- >>> p = Person('Bob', 'male')
- >>> p('Tim')
- My name is Bob...
- My friend is Tim...
- 第四节的斐波那契数列问题,可以改用call实现。
- class Fib(object):
- def __call__(self,num):
- a=0
- b=1
- L=[]
- for n in range(1,num+1):
- L.append(a)temp = b
- b = a + b
- a = temp
- return L
- f = Fib()
- print f(10)
- 参考代码:
- 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 L
- f = Fib()
- print f(10)
注意代码中 高亮语句,使用参考代码的写法,就省去了一个中间变量。
Python 定制类 特殊方法
来源: http://www.bubuko.com/infodetail-2025688.html