-
__str__()
在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法
当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据class Student(object): def __init__(self, name): self.name = name def __str__(self): return 'Student object (name: %s)' % self.name
打印:
print(Student('Michael')) Student object (name: Michael)
-
__repr__()
直接显示变量调用的不是__str__(),而是__repr__(),两者的区别是__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,repr()是为调试服务的。
在类中令__repr__ = __str__,那么直接显示变量也会返回 __str__里面的return
-
__iter__()
class Fib(object):
def init(self):
self.a, self.b = 0, 1 # 初始化两个计数器a,bdef __iter__(self): return self # 实例本身就是迭代对象,故返回自己 def __next__(self): self.a, self.b = self.b, self.a + self.b # 计算下一个值 if self.a > 100000: # 退出循环的条件 raise StopIteration() return self.a # 返回下一个值
输出
for n in Fib(): ... print(n) ... 1 1 2 3 5 ... 46368 75025
-
__getitem__()
1.Fib实例虽然能作用于for循环,看起来和list有点像,但是,把它当成list来使用还是不行,比如,Fib()[5]就会报错
那么我们可以用__getitem__()方法
class Fib(object): def __getitem__(self, n): a, b = 1, 1 for x in range(n): a, b = b, a + b return a
输出:
>>>f = Fib() >>>f[0] 1 >>>f[1] 1 >>> f[2] 2 >>> f[3] 3 >>> f[10] 89 >>> f[100] 573147844013817084101
2.但list有个神奇的切片方法而Fib却会报错
原因是__getitem__()传入的参数可能是一个int,也可能是一个切片对象slice,所以要做判断:
class Fib(object): def __getitem__(self, n): if isinstance(n, int): # n是索引 a, b = 1, 1 for x in range(n): a, b = b, a + b return a if isinstance(n, slice): # n是切片 start = n.start stop = n.stop if start is None: start = 0 a, b = 1, 1 L = [] for x in range(stop): if x >= start: L.append(a) a, b = b, a + b return L
输出:
>>> f = Fib() >>> f[0:5] [1, 1, 2, 3, 5] >>> f[:10] [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
-
__getattr__()
当我们调用class类中没有出现的属性,就会报错,为了避免,我们写一个__getattr__()方法,动态返回一个属性
class Student(object): def __init__(self): self.name = 'Michael' def __getattr__(self, attr): if attr=='score': return 99 s = Student() >>> s.name 'Michael' >>> s.score 99
该方法也可以返回函数,注意的是:只有在没有找到属性的情况下,才调用该函数。如果调用其他没有定义的属性,则会返回None
-
__call__()
当我们调用实例方法时,我们用instance.method()来调用。那么能不能直接在实列本身上调用呢?那么就用到了__call__()
class Student(object): def __init__(self, name): self.name = name def __call__(self): print('My name is %s.' % self.name)
输出
>>> s = Student('Michael') >>> s() # self参数不要传入 My name is Michael.
这样我们就可以把对象看成函数,那么怎么判断一个变量是对象还是函数呢?
那么我们通过一个callable()函数,能被调用的对象就是一个callable对象>>> callable(Student()) True >>> callable(max) True >>> callable([1, 2, 3]) False >>> callable(None) False >>> callable('str') False
我的理解是不能被调用的对象就不是一个callable对象,而被认为是一个对象,而可以被调用的对象可以被认为就是一个函数。
这是区分对象跟函数的标准
python中的定制类
最新推荐文章于 2021-02-03 04:40:55 发布