zoukankan      html  css  js  c++  java
  • 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.
     
  • 相关阅读:
    mac 快捷键
    mac 配置nginx 虚拟域名(转载)
    StringUtils中 isNotEmpty 和isNotBlank的区别【java字符串判空】
    软件常用版本英文snapshot和ga
    IF条件控制
    函数与方法
    数据类型
    函数 FUNCTION
    集合 SET
    字典 DICTIONARY
  • 原文地址:https://www.cnblogs.com/kumata/p/9163846.html
Copyright © 2011-2022 走看看