Python开发Day07

生成器

  介绍:

    • 在使用少量的内存情况下经行这与使用较多内存的性质一样,就是占用内存量少

    • 例如在Python2.*中使用range(1,10)会在内存中直接创建1-9的列表,在Python3.*中range(1,10)他只会在循环时或者__next__时才会起作用

  使用:

    • 在使用生成器是我们需要使用函数和yield来实现。例如:

      def a1(n,n2=None):
          if n2 != None:
              start = n
              while True:
                  if start >= n2:
                      return
                  yield start
                  start += 1
          else:
              start = 0
              while True:
                  if start >= n:
                      return
                  yield start
                  start += 1
      
      for i in a1(2):
          print(i)
      执行结果:
      0
      1
      View Code

       或:

      def a1(n,n2=None):
          if n2 != None:
              start = n
              while True:
                  if start >= n2:
                      return
                  yield start
                  start += 1
          else:
              start = 0
              while True:
                  if start >= n:
                      return
                  yield start
                  start += 1
      aa = a1(2)
      print(aa.__next__())
      print(aa.__next__())
      执行结果:
      0
      1
      View Code

       

迭代器

  介绍:

    • 对于Python 列表的 for 循环,他的内部原理:查看下一个元素是否存在,如果存在,则取出,如果不存在,则报异常 StopIteration。(python内部对异常已处理)

  使用:

    • 利用for循环就是。

 

反射

  介绍:

    • 根据字符串的形式,去对象(或模块)中操作其成员。

    • 反射是通过字符串的形式操作对象相关的成员。

  使用:

    • getattr方法:

      import test#导入自定义模块test
      a = input('请输入')#自定义输入内容
      ac = getattr(test,a)#使用模块test下的a方法
      ac()#执行a方法
      
      执行结果:
      请输入login
      登陆成功!
      View Code
    • hasattr方法:

      import test#导入自定义模块test
      a = input('请输入')#自定义输入内容
      ac = hasattr(test,a)#判断模块test下有没有用户输入的a方法
      print(ac)#输出结果True为有用户输入的方法,False为没有
      
      执行结果:
      请输入login
      True
      View Code
    • setattr方法:

      import test#导入自定义模块test
      setattr(test,'age','hello')#在test模块下设置一个变量为age值为hello
      ac = getattr(test,'age')#将test模块下的age变量给ac
      print(ac)#查看ac的值
      
      执行结果:
      hello
      View Code
    • delattr方法:

      import test#导入自定义模块test
      a = hasattr(test,'login')#判断test模块下有没有login方法
      print(a)#输出True或Flase
      delattr(test,'login')#删除login方法
      a = hasattr(test,'login')#判断test模块下有没有login方法
      print(a)#输出True或Flase
      
      执行结果:
      True
      False
      View Code
    • test模块内容:

      #!/usr/bin/python
      # -*- coding: utf-8 -*-
      __author__ = 'WuYongQi'
      def login():
          print('登陆成功!')
          return 'Yes'
      def logout():
          print('退出成功!')
          return 'No'
      def Nb():
          print('太牛逼了')
          return 'NB'
      View Code
    • 综合调用:

      url = input('请输入网站:')#用户输入网站以字符串的形式保存,例如(test/login)
      inp_modul,inp_user = url.split('/')#将用户输入的url以/分割,(['test','login'])
      modul = __import__(inp_modul,fromlist=True)#使用__import__以字符串的形式导入模块,(导入test,并且支持路径的拼接)
      if hasattr(modul,inp_user):#判断用户输入的模块名和函数是否存在
          a = getattr(modul,inp_user)#用户输入的存在执行getattr将函数赋值给变量a
          a()#执行a函数
      else:#否则函数不存在报404
          print('404')
      
      执行结果:
      请输入网站:test/login
      登陆成功!
      View Code

       

       

面向对象

   介绍:

    • 面向对象是:对函数进行分类和封装,让开发“更快更好更强...”

    • 面向过程是:根据业务逻辑从上到下写垒代码、

    • 函数式编程是:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可

    • 面向对象编程不是所有地方都适用的,因为有些时候函数式编程会比面向对象代码量更少更好。

      • 如果你写了一个函数需要传很多次参数就可以使用面向对象

      • 如果写了一个函数,各个函数之间是独立且无共用的数据,推荐使用函数式编程

  使用:

    • 创建一个类:

      class hhha:    #class为关键字,hhha为类名称
          def test(self):
              print('hello')
              
      obj = hhha()    #调用hhha类
      obj.test()    #执行hhha类中的test方法
    • 面向对象的三大特新:

      • 封装:就是将内容封装到某个地方,以后需要时去被封装的地方调用需要的内容。

        • 在使用面向对象封装的时候我们需要

          • 将内容封装到某处

            class test:#创建一个test类
                def __init__(self,name,age):    #self为特殊参数必须填写(在执行类的时候会给类附一个对象self就是那个对象的意思)
                    self.name=name
                    self.age=age
            
            a = test('Wu',20)#将Wu和20封装到a的self.name和self.age属性中
            View Code

             封装后的对象是独立出现的,例如内存中有一个obj1=test('Wu','20'),一个obj2=test('Yong','21'),那么在内存他们各自有各自的内存地址并且存储的内容也不同

          • 从某处调用被封装的内容
            • 调用被封装的内容时,有两种情况:
              • 通过对象直接调用
                class test:
                    def __init__(self,name,age):
                        self.name = name
                        self.age = age
                    def hello(self):
                        print(self.name,self.age)
                
                a = test('WuYongqi',21)
                print(a.name)
                print(a.age)
                
                执行结果:
                WuYongqi
                21
                View Code
              • 通过self间接调用
                class test:
                    def __init__(self,name,age):
                        self.name = name
                        self.age = age
                    def hello(self):
                        print('%s \n%s'%(self.name,self.age))
                
                a = test('WuYongqi',21)
                a.hello()# Python默认会将a传给self参数,即:a.hello(a),所以,此时方法内部的 self = a,即:self.name 是 WuYongqi;self.age 是 20
                执行结果:
                WuYongqi 
                21
                View Code
          • 使用封装写一个模拟人生:
            class monirensheng:
                def __init__(self,name,genter,jingyan=0):
                    self.name=name
                    self.genter=genter
                    self.jingyan=jingyan
            
                def xiulian(self):
                    self.jingyan += 100
                    print('%s 获得经验100'%self.name)
                    print('%s 当前经验为 %d'%(self.name,self.jingyan))
                    print('__________________________________________________________')
            
                def daBOSS(self):
                    self.jingyan += 1500
                    print('%s 获得经验1500'%self.name)
                    print('%s 当前经验为 %d'%(self.name,self.jingyan))
                    print('__________________________________________________________')
            
                def jiehun(self):
                    self.jingyan += 1000
                    print('%s 因结婚系统奖励1000经验'%self.name)
                    print('%s 当前经验为 %d'%(self.name,self.jingyan))
                    print('__________________________________________________________')
            
            import pickle
            a=pickle.load(open('db.log','rb'))
            #a=monirensheng('Wu','man',)
            while True:
                print("1.打BOSS\n2.修炼\n3.退出")
                ab=input('').strip()
                if ab:
                    if ab.isdigit():
                        if int(ab) == 1:
                            a.daBOSS()
                        elif int(ab) == 2:
                            a.xiulian()
                        elif int(ab) == 3:
                            break
                        else:
                            print('输入有误!')
                    else:
                        print('输入有误!')
                else:
                    print('输入有误!')
            pickle.dump(a,open('db.log','wb'))
            View Code

             利用了pickle

      • 继承:面向对象中的继承就犹如现实生活中的儿子可以继承父亲的关系。

        • 写一个关于猫狗的继承关系,因为猫狗同属于动物,吃喝拉撒为一个类,自己的特性为一个类
          class Animal:#父类也称为基类
          
              def eat(self):
                  print("%s 吃 " %self.name)
          
              def drink(self):
                  print("%s 喝 " %self.name)
          
              def shit(self):
                  print("%s 拉 " %self.name)
          
              def pee(self):
                  print("%s 撒 " %self.name)
          
          
          class Cat(Animal):#子类称之为派生类
          
              def __init__(self, name):
                  self.name = name
          
              def cry(self):
                  print('喵~~~~')
          
          class Dog(Animal):#子类称之为派生类
          
              def __init__(self, name ):
                  self.name = name
          
              def cry(self):
                  print('汪~~~')
          
          
          c1 = Cat('')
          c1.eat()
          
          c2 = Cat('')
          c2.drink()
          
          d1 = Dog('')
          d1.eat()
          
          执行结果:
          猫 吃 
          猫 喝 
          狗 吃 
          View Code
        • 多继承:在Python中一个子类可以继承多个父类,但是他们之间的关系是怎么样的呢?
          class A:
              def f1(self):
                  print('A')
          class B(A):
              def f1(self):
                  print('B')
          class C(A):
              def f1(self):
                  print('C')
          class D:
              def f1(self):
                  print('D')
          class E:
              def f1(self):
                  print('E')
          class F(D,E):
              def f1(self):
                  print('F')
          abc = F()
          abc.f1()
          执行结果:
          F
          View Code

          多继承关系图

      • 多态

        •  Pyhon是不支持多态的并且也用不到多态,多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚的是“鸭子类型”。
          class F1:
              pass
          
          
          class S1(F1):
          
              def show(self):
                  print 'S1.show'
          
          
          class S2(F1):
          
              def show(self):
                  print 'S2.show'
          
          def Func(obj):
              print obj.show()
          
          s1_obj = S1()
          Func(s1_obj) 
          
          s2_obj = S2()
          Func(s2_obj) 
          View Code

           多态不需要知道太深,了解一下就可以!

      • 一张图片介绍类和对象在内存中是如何保存的:

         

    • 一个类是用什么创建的?

      • 在Python中一切事物皆是对象

      • 类生成对象,创建类使用的是type

  

面向对象进阶:

  • 成员:

    • 字段:

      • 静态字段:每个对象都有一份的时候
        • 在class下直接使用变量的形式来创建字段
        • 静态字段在类中的话可以使用类名.静态字段名。(自己去访问自己的成员)
        • 自己去访问自己的成员除了类中的方法不要让对象去访问
      • 普通字段:每个对象都是不同数据的时候
    • 方法:

      class ttt:
          country = '中国' # 静态字段
          def __init__(self,name):#构建
              self.name = name
              temp = 'Hello' #普通方法,对象中
      
          #静态方法
          @staticmethod
          def hello(a,c):
              print(a,c)
      
          #普通方法
          def show(self):
              print(self.name)
      
          @classmethod
          def word(cls):
              print('hello word\t\t\t%s'%cls)
      
      ttt.word()
      ttt.hello(111,222)
      print(ttt.country)
      
      执行结果:
      hello word            <class '__main__.ttt'>
      111 222
      中国
      View Code
      • 静态方法:不使用对象封装的内容的时候(由类调用)
        • @statcmetchod将类中的某一个方法转换成静态方法
      • 类方法:需要当前这个类的时候使用。(由类调用)
        • @classmetchod将类中的方法转成类的方法。
        • 必须要有一个cls参数
        • 执行:类名称.方法名()
      • 普通方法:要使用对象中数据的时候。(由对象调用)
    • 特性:

      class test:
          def __init__(self,name):
              self.name = name
          def hello(self):
              ab = self.name
              return ab
      
          @property
          def hello2(self):
              a=self.name+'123'
              return a
      
          @hello2.setter
          def hello2(self,name):
              print(name)
              self.name = name
      
      ab = test('alex')
      a1=ab.hello()
      a2=ab.hello2
      print(a1,a2)
      ab.hello2 = '????'#设置属性
      a1=ab.hello()
      a2=ab.hello2
      print(a1,a2)
      
      执行结果:
      alex alex123
      ????
      ???? ????123
      View Code
      • 普通特性:为了把方法伪装成字段的形式来访问
        • @property将类中原来的方法伪装成字段的方法去获取
        • @end.setter设置对应特性方法的值
        • 在使用特性后的方法不可以添加参数了
    • 判断是使用类还是对象执行:

      • 在使用特性后的方法不可以添加参数了
      • 有self,对象调用
  • 成员修饰符:

    class tst:
        __ab = '123a'
        ac = 'nihao'
        def __init__(self):
            self.__name= '???我'
    
        def hello(self):
            print(self.__name)
    
    obj = tst()
    print(obj._tst__name)
    
    执行结果:
    ???我
    View Code
    • 每一个类的成员都有两种形式

      • 共有成员:在任何地方都可以访问使用的。(类、类的内部、派生类)
      • 私有成员:只能在类的内部使用和访问。(类的内部)
      • 如果想要强制访问私有字段,可以通过  对象名._类名__私有字段明  来访问(如:obj._C__foo),不建议强制访问私有成员。
    • 私有成员和共有成员的定义

      • 私有成员命名时,前两个字符是下划线。(特殊成员除外,例如:__init__、__call__、__dict__等)
      • 公共成员及正常定义
  • 面向对象中一些常用的特殊成员:

    class Foo:
        '''
        类的注释
        '''
        def __init__(self):
            print('init')
        def __call__(self, *args, **kwargs):
            print('hello')
            return 1
        def __delitem__(self, key):
            print(key)
    
        def __getitem__(self, item):
            print(item)
    
        def __setitem__(self, key, value):
            print(key,value)
    
        def __iter__(self):
            yield 1
            yield 2
            yield 4
            yield 2
    
    
    print(Foo()())
    ab = Foo()  #__call__
    ab['hello']     #__getitem
    ab['hello'] = 'word'    #setitem
    del ab['asdvnadksga']      #delitem
    ab[1:5]     #getitem
    ab[1:5] = [11,22,33,44]     #setitem
    del ab[1:2]     #delitem
    print(ab.__dict__)
    print(Foo.__dict__)
    for i in ab:
        print(i)
    
    
    执行结果:
    init
    hello
    1
    init
    hello
    hello word
    asdvnadksga
    slice(1, 5, None)
    slice(1, 5, None) [11, 22, 33, 44]
    slice(1, 2, None)
    {}
    {'__setitem__': <function Foo.__setitem__ at 0x000001D37C3872F0>, '__getitem__': <function Foo.__getitem__ at 0x000001D37C387268>, '__module__': '__main__', '__init__': <function Foo.__init__ at 0x000001D37C3870D0>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': '\n    类的注释\n    ', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__iter__': <function Foo.__iter__ at 0x000001D37C387378>, '__delitem__': <function Foo.__delitem__ at 0x000001D37C3871E0>, '__call__': <function Foo.__call__ at 0x000001D37C387158>}
    1
    2
    4
    2
    View Code
    • __doc__ :表示类的描述信息。

    • __getitem__ :在对象后跟[]默认执行getitem方法

    • __setitem__ :在对象后跟[]= 值 默认执行__setitem__

    • __delitem__ :del[值] 默认执行__delitem__

    • __getslice__ :在Python2.*列表分割使用该方法,在Python3.*之后就是getitem

    • __module__ :表示当前操作的对象在那个模块。

    • __class__ :表示当前操作的对象的类是什么。

    • __init__ :构造方法,通过类创建对象时,自动触发执行。

    • __del__ :析构,解释器销毁对象的时候自动调用。

    • __dict__ :查看类或对象中的所有成员。

    • __call__ :对象后面加括号,触发执行。(构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()())

    • __iter__ :迭代器

    • __srt__ :使用print对象的时候默认执行__str__方法

 

异常处理

  • 介绍:

    • 在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面,通俗来说就是不让用户看见大黄页!!!

  • 使用:

    • 让用户输入一个数字并且转换成int类型,如果用户输入的是字符串则会报错:

      inp = input('请输入')
      try:
          a = int(inp)
      except Exception as e:
          print(e)
      
      执行结果:
      请输入s
      invalid literal for int() with base 10: 's'
    • 我们一些常见的异常:

      AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
      IOError 输入/输出异常;基本上是无法打开文件
      ImportError 无法引入模块或包;基本上是路径问题或名称错误
      IndentationError 语法错误(的子类) ;代码没有正确对齐
      IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
      KeyError 试图访问字典里不存在的键
      KeyboardInterrupt Ctrl+C被按下
      NameError 使用一个还未被赋予对象的变量
      SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
      TypeError 传入对象类型与要求的不符合
      UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
      导致你以为正在访问它
      ValueError 传入一个调用者不期望的值,即使值的类型是正确的
      View Code
    • 其他的异常

      ArithmeticError
      AssertionError
      AttributeError
      BaseException
      BufferError
      BytesWarning
      DeprecationWarning
      EnvironmentError
      EOFError
      Exception
      FloatingPointError
      FutureWarning
      GeneratorExit
      ImportError
      ImportWarning
      IndentationError
      IndexError
      IOError
      KeyboardInterrupt
      KeyError
      LookupError
      MemoryError
      NameError
      NotImplementedError
      OSError
      OverflowError
      PendingDeprecationWarning
      ReferenceError
      RuntimeError
      RuntimeWarning
      StandardError
      StopIteration
      SyntaxError
      SyntaxWarning
      SystemError
      SystemExit
      TabError
      TypeError
      UnboundLocalError
      UnicodeDecodeError
      UnicodeEncodeError
      UnicodeError
      UnicodeTranslateError
      UnicodeWarning
      UserWarning
      ValueError
      Warning
      ZeroDivisionError
      View Code
    • 捕捉异常(IndexError): 

      a = [11,22,33,44]
      try:
          print(a[5])
      except IndexError as e:
          print(e)
      
      执行结果:
      list index out of range
      View Code

      这样的定义如果说出现一个错误不是IndexError异常那么就不会捕捉:

      a = [11,22,33,44]
      try:
          print(a['asd'])
      except IndexError as e:
          print(e)
      
      执行结果:
      Traceback (most recent call last):
        File "F:/oldboy-Python/py_code/test/day06/class_next/test123.py", line 165, in <module>
          print(a['asd'])
      TypeError: list indices must be integers or slices, not str
      View Code
    • 从上述中我们可以看出来捕捉异常只能捕捉一个,那么想捕捉多个怎么办?

      imp = 'asdfds'
      try:
          num = int(imp)
          print(num)
      except ValueError:#捕捉ValueError错误
          print('数据类型转换失败!')
      except TypeError as a:#捕捉TypeError错误
          print(a)
      except Exception as e:#捕捉所有出现的错误
          print('出现位置错误式发发送给管理员')
      
      执行结果:
      数据类型转换失败!
      View Code
    • 异常的其他结构:

      try:
          # 主代码块
      except KeyError,e: # KeyError错误
          # 异常时,执行该块
          pass
      else:
          # 主代码块执行完,执行该块
          pass
      finally:
          # 无论异常与否,最终执行该块
          pass
      View Code
    • 我们设置一个主动触发的异常,就是说本来没有错但是我们希望他报错:

      try:
          num = int(imp)
          print(num)
          raise TypeError('出现问题,请联系管理员进行处理!')
      except ValueError:#捕捉ValueError错误
          print('数据类型转换失败!')
      except TypeError as a:#捕捉TypeError错误
          print(a)
      except Exception as e:#捕捉所有出现的错误
          print('出现位置错误式发发送给管理员')
      
      执行结果:
      请输入1
      1
      出现问题,请联系管理员进行处理!
      View Code
    • 断言:

      • 差不多和判断一样如判断通过则通过,不通过直接触发错误
        imp = 1
        try:
            assert imp == 2
            print(imp)
            raise TypeError('出现问题,请联系管理员进行处理!')
        except ValueError:#捕捉ValueError错误
            print('数据类型转换失败!')
        except TypeError as a:#捕捉TypeError错误
            print(a)
        except Exception as e:#捕捉所有出现的错误
            print('出现位置错误以发送给管理员')
        
        执行结果:
        出现位置错误以发送给管理员
        View Code

         

单例模式

  • 介绍:

    • 单例,顾名思义单个实例。

    • 假如说是我们做了一个服务端,当用户来访问的时候执行一个类(这个类的值是固定不变的),那么如果有一万个用户来访问这个类就执行一万次,这样的话有些浪费内存所以当值是固定的时候最好使用单列模式

  • 使用:

    • 单例模式就是用来保证内存中仅存在一个实例!!!

      class Foo(object):#创建一个类
          __instance = None  # 定义一个私有成员值为None
          @staticmethod
          def singleton():  # 定义一个静态方法
              if Foo.__instance:  # 判断类中的私有成员值是不是成立,None是不成立的
                  return Foo.__instance  # 如果成立就把这个类的对象返回
              else:  #判断类中的私有成员是不成立的
                  Foo.__instance = Foo()  # 将类中的私有成员定义成对象
                  return Foo.__instance  #返回这个类的对象返回
      
      
      obj = Foo.singleton()  # 将Foo类创建一个对象为obj,并执行类中的singleton方法
      View Code
    • 使用网页来做一个单例模式

      from wsgiref.simple_server import make_server
      
      class ConnectionPool:
      
          __instance = None
      
          def __init__(self):
              self.ip = "1.1.1.1"
              self.port = 3306
              self.pwd = "123123"
              self.username = 'xxxx'
              # 去连接
              self.conn_list = [1,2,3,4,5,6,7,8,9, 10]
      
          @staticmethod
          def get_instance():
              if ConnectionPool.__instance:
                  return ConnectionPool.__instance
              else:
                  # 创建一个对象,并将对象赋值给静态字段 __instance
                  ConnectionPool.__instance = ConnectionPool()
                  return ConnectionPool.__instance
      
          def get_connection(self):
              # 获取连接
              import random
              r = random.randrange(1,11)
              return r
      
      def index():
          # p = ConnectionPool()
          # print(p)
          p = ConnectionPool.get_instance()
          conn = p.get_connection()
          return "conn" + str(conn)
      
      def news():
          return 'new'
      
      def RunServer(environ, start_response):
          start_response(status='200 OK', headers=[('Content-Type', 'text/html')])
      
          url = environ['PATH_INFO']
          if url.endswith('index'):
              ret = index()
              return ret
          elif url.endswith('news'):
              ret = news()
              return ret
          else:
              return ' 404 '
      
      
      if __name__ == '__main__':
          httpd = make_server('', 8080, RunServer)
          print("Serving HTTP on port 8008...")
          httpd.serve_forever()
      
      
      使用Python2.7执行,3.*有些问题,执行后使用浏览器访问127.0.0.1:8080或者127.0.0.1:8080/index或者127.0.0.1:8080/news或者127.0.0.1:8080/任何
      View Code

       

 学生选课练习题!要求:

选课系统

管理员:
    创建老师:姓名、性别、年龄、资产
    创建课程:课程名称、上课时间、课时费、关联老师
    使用pickle保存在文件
学生:
    学生:用户名、密码、性别、年龄、选课列表[]、上课记录{课程1:【di,a,】}
    1、列举所有课程
    2、选择课程
    3、学生上课,
    4、ret = 课程.work() 获取课程的返回; 资产+=课时费
View Code

 

代码单机这里!

 

posted @ 2016-06-01 18:49  WuYongQi。  阅读(272)  评论(0)    收藏  举报