Skip to content

Commit d731d82

Browse files
authored
练习面向对象的高级特性的定制类
1 parent 445ba9d commit d731d82

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed

test24.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#!/usr/bin/env python 3
2+
# -*- coding: utf-8 -*-
3+
4+
'练习面向对象的高级特性的定制类'
5+
6+
__author__ = 'sergiojune'
7+
8+
9+
class Fib(object):
10+
# 在实例化时会调用该方法
11+
def __init__(self):
12+
self.name = 'Fib'
13+
self.a = 0
14+
self.b = 1
15+
16+
# 在调用len方法时实际调用的是该方法
17+
def __len__(self):
18+
return 100
19+
20+
# 在打印实例信息时调用该方法
21+
def __str__(self):
22+
return 'object name is %s' % (self.name)
23+
24+
# 因为一般这两个方法代码一样,所以这样做
25+
__repr__ = __str__
26+
27+
# 这个方法让实例可迭代,返回的是一个可迭代对象
28+
def __iter__(self):
29+
return self
30+
31+
# 这个方法当实例用于for循环时会被调用,与list,tuple类似
32+
def __next__(self):
33+
self.a, self.b = self.b, self.a + self.b
34+
# 到达指定数目就返回一个异常
35+
if self.a > 100000:
36+
raise StopIteration
37+
return self.a
38+
39+
# 该方法当实例在用下标取元素时被调用,传入切片也是调用这个函数
40+
# 该方法也可以像dict那样用键来获取值,判断参数是否是字符串即可
41+
def __getitem__(self, num):
42+
# 对参数进行判断
43+
if isinstance(num, slice):
44+
start = num.start
45+
end = num.stop
46+
step = num.step
47+
# 开头可能不填
48+
start = start if start else 0
49+
# 步长也一样
50+
step = step if step else 0
51+
L = []
52+
if step == 0:
53+
for x in range(start, end):
54+
L.append(Fib()[x])
55+
else:
56+
for x in range(start, end, step):
57+
L.append(Fib()[x])
58+
return L
59+
else:
60+
n = 0
61+
for x in Fib():
62+
if n == num:
63+
return x
64+
n += 1
65+
66+
# 该方法当用下标设置对应值时被调用,也可以像dict一样的赋值
67+
def __setitem__(self, index, value):
68+
# 和上面的差不多,就不实现了
69+
pass
70+
71+
# __delitem__():方法是当删除某个值时就会被调用
72+
73+
74+
fib = Fib()
75+
print(len(fib))
76+
# 打印实例
77+
print(Fib())
78+
# 打印有变量指向的实例信息
79+
print(fib)
80+
# 用类实现斐波那契数列
81+
for x in fib:
82+
print(x)
83+
print('-----------')
84+
print(fib[5])
85+
# 切片
86+
print(fib[1:5])
87+
# 有步长
88+
print(fib[5:1:-2])
89+
90+
91+
class Student(object):
92+
def __init__(self, name):
93+
self.name = name
94+
95+
# 这个方法当实例方法不存在的属性时被调用
96+
def __getattr__(self, name):
97+
if name == 'score':
98+
return 99
99+
raise AttributeError('\'Student\' object has no attribute \'%s\'' % name)
100+
101+
# 这个方法就是当实例当函数被调用时调用这个方法,还可以传参数
102+
def __call__(self):
103+
print('call Student')
104+
105+
106+
stu = Student('bart')
107+
print(stu)
108+
# 访问不存在的属性,加了__getattr__方法后就不会报错
109+
print(stu.score)
110+
# print(stu.j)
111+
# 将实例当函数调用
112+
stu()
113+
# 判断对象是否可被调用
114+
print(callable(stu))
115+
print(callable([1]))
116+
print(callable(fib))
117+
118+
119+
# 实现教程中的Chain().users('michael').repos 得到 GET /users/:user/repos
120+
class Chain():
121+
def __init__(self, path='GET'):
122+
self.path = path
123+
124+
def __getattr__(self, path):
125+
if path:
126+
return Chain('%s/%s' % (self.path, path))
127+
128+
def __str__(self):
129+
return self.path
130+
131+
def __call__(self, user):
132+
return Chain('%s/:%s' % (self.path, user))
133+
134+
135+
chain = Chain()
136+
print(Chain().users('michael').repos)

0 commit comments

Comments
 (0)