Python知识点 -- 5.1 定制类(使用__str__,__getitem__,__item__和__next__)

在Python中,形如__xx__形式的变量名或函数名都是有特殊用途的,例如__slots__就是用来限制当前类的属性的,因此可以使用这些特殊作用的函数来自定义类。

__str__方法

当我们定义好一个类后,直接输出当前类的一个实例:

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


print(Persom('Lee'))

结果:
<__main__.Person object at 0x0000000002471198>
表示这个实例是一个Person对象,所在的内存地址就是后面的十六进制数
而如果在类中地定义好__str__()方法,他就会返回你想要自定义显示的结果了,如:

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

    def __str__(self):
        return ('Person object: \n(name: {})'.format(self.name))


print(Person('Lee'))

结果:

Person object:
(name: Lee)

这样你就可以直接看出实例内部拥有那些数据了。
如果是在控制台运行python并将一个实例赋给一个变量然后直接看变量内容而不用print你会发现:

>>> a = Person('Lee')
>>> a
<__main__.Person object at 0x0000000002566860>

打印出的还是刚才没定义的__str__时的结果,这是因为直接显示变量调用的是__repr__()方法,主要是为了程序员调试用的,而__str__主要是返回给用户看的。
所以只要再定义一个__repr__()就可以了,但一般__repr__和__str__代码都是相同的,所以直接写成下面这样就可以了:

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

    def __str__(self):
        return ('Person object: \n(name: {})'.format(self.name))
    __repr__ = __str__
__getitem__方法

此方法可以使当前定义的的类像字符串和列表一样使用索引下标取出各个元素,例如定义一个Fibonacci(斐波那契数列)类:

class Fibonacci(object):
    def __getitem__(self, n):
        a, b = 1, 1
        for x in range(n):
            a, b = b, a + b     # 计算数列的下一个值,即后面一个数等于前面两个数的和
        return a

现在就可以使用下标进行取值了:

a = Fibonacci()
print(a[0],a[1],a[2],a[3],a[4],a[5],a[6])

结果:
1 1 2 3 5 8 13
但列表还有一种特别好用的切片方法:

print(list(range(6))[2:5])

结果:
[2, 3, 4]
而这种方法用在Fibonacci上就会报错,因为其中没有对__getitem__的参数为切片对象(slice)时的处理,所以需要在传入参数时进行对象的判断处理:

class Fibonacci(object):
    def __getitem__(self, n):
        if isinstance(n, int):    # 如果传入参数是整型数
            a, b = 1, 1
            for x in range(n):
                a, b = b, a + b
            return a
        if isinstance(n, slice):    # 如果传入参数是切片
            start = n.start
            stop = n.stop
            if stop is None:
                start = 0
            a, b = 1, 1
            lt = []
            for x in range(stop):
                if x >= start:    # 过滤掉切片起始前的数
                    lt.append(a)
                a, b = b, a + b
            return lt

这样就可以进行切片了:

a = Fibonacci()
print(a[2:6])

结果:
[2, 3, 5, 8]

__iter__方法、__next__方法

__iter__方法返回一个迭代对象,for循环不断的调用该迭代对象的__next__方法拿到循环的值,直到达到设定的某个条件是抛出StopIterration错误退出循环:

class Fibonacci(object):
    def __init__(self):
        self.a, self.b = 0, 1

    def __iter__(self):
        return self         # 实例自己就是一个迭代对象,所以返回自身
    
    def __next__(self):
        self.a, self.b = self.b, self.a + self.b    # 计算下数列中的下一个值
        if self.a > 66:  # 计算下一个值到特定条件时退出循环
            raise StopIteration()
        return self.a   # 返回下一个值

此时就可以用作for循环了:

for x in Fibonacci():
    print(x)

结果:

1
1
2
3
5
8
13
21
34
55
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值