zoukankan      html  css  js  c++  java
  • 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()函数,我们就可以判断一个对象是否是“可调用”对象。

  • 相关阅读:
    Eclipse新建工程编译R cannot be resolved to a variable问题
    Eclipse如何生成jar包
    Springmvc+Shiro实战
    封装springmvc处理ajax请求结果
    jquery操作cookie
    探讨jsp相对路径和绝对路径
    spring集成quartz
    Spring-Task
    bootstrap table分页(前后端两种方式实现)
    jquery file upload示例
  • 原文地址:https://www.cnblogs.com/twlr/p/12330959.html
Copyright © 2011-2022 走看看