Python学习笔记之定制类

1.实现一个较为完整的定制类,支持初始化,输出自定义实例、类对象信息,len()调用,for in,[],获取默认属性,以及调用instance():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Custom(object):

__slots__ = ('_name','index')

def __init__(self,name):
self._name = name
self.index = -1

def __str__(self):
return 'Custom Instance => (name: %s)' % self._name

__repr__ = __str__

def __len__(self):
return len(self._name)

def __iter__(self):
return self

def next(self):
self.index+=1
if self.index >= len(self._name):
raise StopIteration();
return self._name[self.index]

def __getitem__(self,n):
return self._name[n]

def __getattr__(self,attr):
if attr=='func':
return lambda: 'FFF'
elif attr=='attr':
return 'attr'
raise AttributeError('\'Custom\' object has no attribute \'%s\'' % attr)

def __call__(self):
print "Instance's name is %s." % self._name

2.链式调用
对应问题定制类-廖雪峰

看评论前自己想到的做法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Chain(object):

def __init__(self,user=':user'):
self._user = user

def __getattr__(self,attr):
if attr=='users':
'''
方法一:
def func(name):
self._user=name
return self
setattr(self,'users',func)
return self.users
方法二:
return lambda name:Chain(name)
方法二可能有局限
'''
return lambda name:Chain(name)
elif attr=='repos':
return 'GET /users/%s/repos' % self._user
raise AttributeError('\'Chain\' object has no attribute \'%s\'' % attr)

def __str__(self):
return self._user
__repr__ = __str__

看完评论之后的做法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Chain(object):

def __init__(self,path=''):
self._path = path

def __getattr__(self,path):
return Chain('%s/%s' % (self._path, path))

def __str__(self):
return self._path
__repr__ = __str__

def __call__(self,path):
if path=='users':
return Chain('%s/%s' % (self._path, path))
return self

在看教程时,__call__是在后面介绍的,所以我先前的做法并没有涉及到’__call__,看完这篇教程和后面的评论以后,作出了一些修改。