Python定制类

#最近再根据廖雪峰老师的python学习教程学习,以下是学习过程中做的一些学习总结

定制类

  在python中,类似__xxx__的变量都属于特殊变量,可以帮助我们定制类。

__iter__

  如果想要一个类被用于for...in...循环,类似于list或者tuple那样就用到了__iter__方法,这个特殊变量返回一个迭代对象,python使用该方法时就会不断调用该方法,并且利用__next__()方法循环下一个值:

class Fib(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 > 100:
            return raise StopIteration()
        return self.a

  然后我们使用for...in..循环来看下结果:

>>> for x in Fib():
    print(x)

    
1
1
2
3
5
8
13
21
34
55
89

__getitem__

  Fib虽然能用于for循环,看起来和list很像,但是并不能当作list来使用,例如:

>>> Fib()[5]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'Fib' object does not support indexing

  如果想要class可以像list那样使用则需要__getitem__方法:

class Fbi(object):
    def __getitem__(self,n):
        self.n = n
        a,b = 0,1
        for x in range(n):
            a,b = b,a+b
        return a

  我们就可以访问获取数列的值:

>>> a = Fbi()
>>> a[5]
8
>>> a[1]
1
>>> a[10]
89

  但是list有一个切片方法,而__getitem__会报错,原因是__getitem__传入的参数可能是个int,也可能是个slice,所以需要进行判断:

class Fbi(object):
    def __getitem__(self,n):
        if isinstance(n,int):
            a,b = 0,1
            for x in range(n):
                a,b = b,a+b
            return a
        if isinstance(n,slice):
            start = n.start
            stop = n.stop
            if start == None:
                start = 0
            a,b =0,1
            L =[]
            for x in  range(stop):
                if x >= start:
                    L.append(a)
                    a,b=b,a+b
            return L

  这样我们就可以进行切片操作:

>>> a = Fbi()
>>> a[0:5]
[0, 1, 1, 2, 3]

__getattr__

  在python类中,我们会绑定属性,但是如果我们访问不存在的属性时则会报错,这个时候可以用到__getattr__方法

  __getattr__方法会给class设定一个动态属性,如果class中不存在该属性时,则会调用动态属性。

class Fbi(object):
    def __init__(self,name):
        self.name = 'Bob'
    def __getattr__(self,attr):
        if attr = 'score':
            return 0

  当调用不存在的score属性时就会调用动态属性:

>>>a = Fbi()
>>>a.score
0

  只有当__init__中没有属性时才会调用动态属性,如果绑定属性存在的化,则不会调用。

__call__

  在python中存在调用实例的方法__call__,只要定义call()方法,我们就可以在类中调用实例本身:

class Student(objecct):
    def __init__(self,name):
        self.name = name
    def __call__(self):
        print('My name is %s' % self.name)

  调用实例:

>>>a = Student('Bob')
>>>a()
My name is Bob

  call还可以定义参数。并且判断一个变量是对象还是函数,可以被调用就是callable对象:

>>> callable(Student())
True
>>> callable(max)
True
>>> callable([1, 2, 3])
False
>>> callable(None)
False
>>> callable('str')
False

  通过callable()函数,我们就可以判断一个对象是否是“可调用”对象。

 

posted @ 2020-02-19 13:37  终落  阅读(349)  评论(0编辑  收藏  举报
页脚Html代码