python--魔法方法,属性和迭代器

一、构造方法:使用双下划线例如__init__。当一个对象被创建后,会立即调用构造方法。

      1、创建构造方法:

       def __init__(self):创建构造方法。

      

 

      往构造方法中传入多个参数:

      

 

      2、重写一般方法和构造方法:

           1、重写一般方法:B类继承了A类,继承了A类的hello方法。

               

            程序运行结果:

            

 

          怎么重写子类B类的方法呢?

          

           程序运行结果:

           

   

          2、重写构造方法:

               以下代码Bird类定义了鸟的eat方法,SongBird类继承了Bird类,重写了__init__构造方法,且定义了sing方法。。

          

              程序运行结果:sb.eat()报错:SongBird没有hungry特性。那是因为在SongBird类中构造方法被重新,新的构造方法中没有关于初始化hungry特性。

         

 

 

          3、调用未绑定的超类的构造方法python旧版本:解决sb.eat()报错的问题。

                以下代码:Bird.__init__(self):调用超类的构造方法。

          

 

                代码运行结果:

         

 

         4、使用super函数:super函数时新式类中的新函数,当前类和对象可以作为super函数的参数使用,调用函数返回的对象的任何方法都是调用超类的方法。

              以下代码:super(SongBird,self).__init__():使用super函数将当前的SongBird类和对象作为参数,返回调用超类的__init__构造方法。使SongBird具有超类Bird的hungry特性。

         

               程序运行结果:

         

 

        5、成员访问(基本的序列和映射规则)

             1、__len__(self):返回集合中所有项目的数量。

             2、__getitem__(self,key):返回所给键对应的值。

             3、__setitem__(self,key,value):按一定的方式存储和key相关的value。

             4、__delitem__(self,key):对一部分对象使用del语句时被调用,同时必须删除和键相关的键。

             以下代码:实现了一个算数序列,每个元素都比前一个元素大1。

             

             checkIndex(key)函数:检查所给的键是不是正常的索引,如果不是整数则引发TypeError异常,如果小于0则引发IndexError异常。

             __init__(self,start=0,step=1):构造方法初始化。

             __getitem__(self,key):获取给定key的值。

             __getitem__(self,key,value):重新保存更改后的值。

            运行程序:

            

            s=ArithmeticSequence(1,2):定义一个s对象,start=1,step=2

            s=[4]:调用__getitem__方法,等价于__getitem__(s,4),计算self.start+key*self.step=1+4*2=9

            s[4]=2:调用__setitem__方法,等价于__setitem__(s,4,2),保存修改值self.changed[4]=2将2赋值给序列key4的位置。

 

           6、子列化列表,字典和字符串:

                 以下代码子列化列表:

                 

                代码运行结果:

                

                 每次调用__getitem__方法获取键值时,counter自增1。

 

          7、属性:通过访问器定义的特性。

               1、property函数:通过访问器函数用作参数(先取值,再赋值)创建属性。

               

                程序运行结果:

                

 

              2、静态方法和类成员方法:

                   静态方法:定义没有self参数,且能够被自身类直接调用。

                   类成员方法:需要cls参数,可以直接用类的具体对象调用。

                   使用装饰器@staticmethod表示这个方法是个静态方法。

                   使用装饰器@classmethod表示这个方法是个类方法。

                   如下代码分别创建一个静态方法与类方法:

                   

                    程序运行结果:

                    

            

                  3、__getattr__、__setattr__:

                       作用:在访问特性时可以执行代码。

                       1、__getattribute__(self,name):当特性name被访问时自动被调用(只能在新式类中使用)。

                       2、__getattr__(self,name):当特性name被访问且对象没有相应特性时被自动调用。

                       3、__setattr__(self,name,value):试图给name特性赋值时被自动调用。

                       4、__delattr__(self,name):试图删除特性name时被自动调用。

                       以下代码:__setattr__方法:如果属性是size则将value值赋值给width与height,如果属性不是size则使用__dict__方法代替普通的特性赋值操作。防止死循环。

                       

                      代码运行结果:

                      

               

             4、迭代器:__iter__返回一个迭代器,迭代器就是具有next方法的对象。

                 1、 如下代码通过迭代器,返回斐波那契数列。

                  

                 

                当fibs=Fibs()生成类的实例时,__init__初始化构造方法被调用,此时实例fibs中有两个变量fibs.a=0,fibs.b=1。

                for f in fibs:表示迭代fibs,赋值给变量f,每次迭代都会自动执行fibs的next方法:fibs.a=fibs.b,fibs.b=fibs.a+fibs.b,然后返回fibs.a。赋值给f。

                设置了break语句:当找到大于10的数后打印,停止循环。

                 

                2、內建函数iter可以从可迭代的对象中获得迭代器。

                

 

                3、从迭代器中获得序列:通过list构造方法显示的将迭代器转换为列表。

                

                

 

           5、生成器:

                任何包含yield语句的函数称为生成器。yield功能类似于return,但不同的是它返回的是一个生成器。

                生成器并不会一次返回所有结果,而是每次遇到yield关键字后返回相应的结果,并保留函数的当前运行状态,等待下一次调用。

                由于生成器也是一个迭代器,那么它就支持next方法

               1、创建生成器:

                如下代码:定义一个生成器,按顺序打印出列表的数字。

                

              

              

             2、递归生成器:

                   如下代码:外层try,except语句:如果函数被告知展开一个元素,引发TypeError异常,生成器产生一个元素。如果函数被告知展开一个列表,则会执行内层的try语句。

                                    内层try,except语句:将传入的对象与一个字符串拼接,看看会不会引发TypeError异常。如果引发则忽略。如果没有引发则else语句会引发自己的TypeError异常。就会按for循环执行。

    

     

                 程序执行结果:

                

 

            3、生成器方法:

                 1、send方法:可以接收外部传的变量,并根据变量计算结果后返回。send方法必须在生成器被挂起后才能使用。

                 2、next方法:应为生成器本身就是一个迭代器,因此具有next方法。

                

               程序运行结果:

               

 

               3、close方法:手动关闭生成器,后面的调用会直接返回StopIteration异常。

               

               

 

              4、throw方法:用来向生成器送入一个异常,可以结束系统定义的异常,或者自定义的异常。

                   throw后直接跑出异常并结束程序,或者消耗掉一个yield,或者在没有下一个yield的时候直接进行到程序的结尾。

                   

                   程序运行结果:

                    

 

             4、模拟生成器:使用普通的函数模拟生成器:

                   

 

              5、八皇后问题:

                   

 

                   定义冲突函数conflict,state参数:是个元组,已知皇后的位置,nextX参数:下一个皇后的水平位置。nextY=len(state):将已有皇后位置的长度赋值给下一个皇后的垂直位置。abs(state[i]-nextX)=0:表示下一个皇后与正在考虑的前一个皇后的水平距离为0(列相同)。abs(state[i]-nextX)=nextY-i:表示在同一对角线上。

                   

                     定义queens函数:num:皇后总数,state=():皇后的位置。if len(state)==num-1:判断当前的皇后是否是最后一个,是则用生成器的方式返回该皇后的位置。for result in queens(num,state+(pos,)):如果不是最后一个皇后,则返回该皇后的位置并为后面的皇后提供当前皇后的每种合法的位置信息。

                   

                    打印皇后位置

 

                    程序运行结果:

                    

 

                  

               

 

               

 

 

 

            

 

   

 

 

      

 

posted @ 2017-07-14 15:52  四平八稳  阅读(233)  评论(0编辑  收藏  举报