0%

Python特殊方法

特殊方法简介

Python之所以能把把任意变量变成str输出,因为任何数据类型的实例都有一个特殊方法str()。

常用特殊方法举例

__str()__

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

1
2
3
4
5
6
7
8
9
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)
__cmp()__

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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)]

上述Student类实现了__cmp__()方法,__cmp__用实例自身self和传入的实例s进行比较,如果self应该排在前面,就返回-1,如果s应该排在前面,就返回1,如果两者相当,返回0。
注意: 如果list不仅仅包含Student类,则__cmp__可能会报错。Python3已经取消该函数

__len()__

如果一个类表现得像一个list,要获取有多少个元素,就得用len()函数。要让len()函数工作正常,类必须提供一个特殊方法__len__(),它返回元素的个数。
例如,写一个Students类,把名字传进去,只要正确实现了__len__()方法,就可以用len()函数返回Students实例的“长度”,

1
2
3
4
5
6
7
8
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
__slots__

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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' # OK
s.score = 99 # OK
.grade = 'A'
Traceback (most recent call last):
...
AttributeError: 'Student' object has no attribute 'grade'

__slots__的目的是限制当前类所能拥有的属性,如果不需要添加任意动态的属性,使用__slots__也能节省内存。slots定义的属性仅对当前类实例起作用,对继承的子类是不起作用的

__call()__

在Python中,函数其实是一个对象。如下,由于f可以被调用,所以,f被称为可调用对象。所有的函数都是可调用对象

1
2
3
f = abs
print(f.__name__) # 'abs'
print(f(-123)) # 123

一个类实例也可以变成一个可调用对象,只需要实现一个特殊方法__call__()。该函数在调用类的实例时自动调用。把Person类变成一个可调用对象如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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)

# 可以对Person实例直接调用:
p = Person('Bob', 'male')
p('Tim')

# My name is Bob...
# My friend is Tim...

单看p('Tim')无法确定p是一个函数还是一个类实例,所以,在Python中,函数也是对象,对象和函数的区别并不显著

天生我材必有用,千金散尽还复来~
  • 本文作者: XTLei
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
-------------本文结束感谢您的阅读-------------