python面向对象高级:定制类

Python的class中还有许多这样有特殊用途的函数,可以帮助我们定制类。

比如:

__str__ 与__repr__
__iter__
__getitem__
__call__

__str__ 与__repr__

class Student(object):
    def __init__(self,name):
        self.name = name 
    '''
    只有以上的话,
    print(Student('kumata'))  
    输出结果:<__main__.Student object at 0x109afb190>
    '''
    def __str__(self):
        return 'student object (name:%s)' % self.name

    '''
    print(Student('kumata'))  
    #student object (name:kumata)
    但是直接 s = (Student('kumata'))然后敲输出s
    还是:<__main__.Student object at 0x109afb310>
    这是因为直接显示变量调用的不是__str__(),而是__repr__(),
    两者的区别是__str__()返回用户看到的字符串,
    而__repr__()返回程序开发者看到的字符串,
    也就是说,__repr__()是为调试服务的。
    解决办法是再定义一个__repr__()。
    但是通常__str__()和__repr__()代码都是一样的,
    所以,有个偷懒的写法:
    '''
    __repr__ = __str__

    

__iter__

如果一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。

我们以斐波那契数列为例,写一个Fib类,可以作用于for循环:

class Fib(object):
    def __init__(self):
        self.a, self.b = 0, 1 # 初始化两个计数器a,b

    def __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 i in Fib():
    print(i)

#输出结果
1
1
2
3
5
...
46368
75025

__getitem__

Fib实例虽然能作用于for循环,看起来和list有点像,但是,把它当成list来使用还是不行,比如:Fib()[5]会抛出错误

要表现得像list那样按照下标取出元素,需要实现__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

__call__

一个对象实例可以有自己的属性和方法,当我们调用实例方法时,我们用instance.method()来调用。能不能直接在实例本身上调用呢?在Python中答案是肯定的。

任何类,只需要定义一个__call__()方法,就可以直接对实例进行调用。

class Student(object):
    def __init__(self, name):
        self.name = name

    def __call__(self):
        print('My name is %s.' % self.name)

#调用方式如下:

>>> s = Student('kumatal')
>>> s()        # self参数不要传入
My name is kumata.
 

猜你喜欢

转载自www.cnblogs.com/kumata/p/9163846.html