学习python课程第二十五天

一.   三层结构:

  1. 用户视图层  : 负责与用户交互 (展示数据,收集数据)

 

  2. 业务逻辑层  : 负责对用户传入的数据, 进行 验证, 判断, 组装

 

  3. 数据访问层  : 负责将业务逻辑层输出后的数据进行持久化存储

 

 

二 .   异常处理:

  1.  什么是异常:

    异常,字面意思就是非常规情况,平时我们看到的异常其实是异常的结果.

    异常是错误发生前的一种信号.

    如果没有人来处理这个信号, 程序就会中断执行并抛出错误信息.

 

    我们之所以学异常处理,  为的是让我们的程序更加稳定.增加健壮性. 不容易崩溃

 

  2. 异常的分类:

    1. 语法检测异常 :

      这种异常是最低级的异常,  绝对不应给犯,

      当然, 这种也很好避免.  如果在编译器上写, 会自动提示.

      如果是文本编辑器, 在运行代码前, 解释器会检查语法.

 

 

    2. 运行时异常 (逻辑异常) : 

      这种异常,只有在代码被执行时才能发现

      我们要处理的重点就是运行时异常

      特点  : 在没有运行代码前,是无法发现的,

      如果运行时异常已经发生并且没有正确处理它,

      就会抛出错误信息, 并且中断程序的执行.

      这是我们学习异常要解决的问题.

      

 

  3.  异常的组成 :

    异常的组成分为三个部分 :

    1.  追踪信息.   (具体发生的位置.   以及函数的调用顺序)

    2. 异常的类型. (描述了为什么发生错误的类型)

    3. 异常的消息. (详细的错误信息)

 

  

  4.  常见的异常:

 

    AttributeError   试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x

    

    IOError   输入/输出异常;基本上是无法打开文件

    

    ImportError   无法引入模块或包;基本上是路径问题或名称错误

    

    IndentationError   语法错误(的子类) ;代码没有正确对齐

    

    IndexError   下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]

    

    KeyError   试图访问字典里不存在的键

    

    KeyboardInterrupt   Ctrl+C被按下

    

    NameError   使用一个还未被赋予对象的变量

    

    SyntaxError   Python代码非法,代码不能编译(个人认为这是语法错误,写错了)

    

    TypeError   传入对象类型与要求的不符合

    

    UnboundLocalError  试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量.

    

    导致你以为正在访问它

    

    ValueError   传入一个调用者不期望的值,即使值的类型是正确的

    

  

  5. 异常的处理 :

    为了保证程序的健壮性与容错性, 即在遇到错误时程序不会崩溃  我们需要对异常进行处理.

    

    1. 常用的异常处理 :

      如果错误发生的条件是可预知的, 我们需要用 if 进行处理, 在错误发生之前进行预防.

 

      示例 : 

         

      AGE=10
      while True:
          age=input('>>: ').strip()
          if age.isdigit():  #只有在age为字符串形式的整数时,下列代码才不会出错,该条件是可预知的
              age=int(age)
              if age == AGE:
                  print('you got it')
                 break

    

      如果错误发生的条件是不可预知的, 则需要用到 try ... except ... :在错误发生之后进行处理

 

      基本语法为 : 

        try :

          # 被检测的代码块

        except  # 异常的类型 :

          # try 中一旦检测到异常, 就执行这个位置的逻辑

 

      示例:

        try:

          f = open('a.txt')

          g = (line.strip()  for line in f)

          print(next(g))

          print(next(g))

          print(next(g))

          print(next(g))

          print(next(g))

        except   StopIteration:

          f . close()

 

 

    

      2 多分支
      
      s1 = 'hello'       try:        int(s1)       except IndexError as e:        print(e)       except KeyError as e:        print(e)       except ValueError as e:        print(e)       3 万能异常Exception       
      s1 = 'hello'       try:        int(s1)       except Exception as e:        print(e)      
      4 多分支异常与万能异常       4.1 如果你想要的效果是,无论出现什么异常,我们统一丢弃,或者使用同一段代码逻辑去处理他们,那么骚年,大胆的去做吧.
      只有一个Exception就足够了。       4.2 如果你想要的效果是,对于不同的异常我们需要定制不同的处理逻辑,那就需要用到多分支了。

 

      

      5 也可以在多分支后来一个Exception
      s1 = 'hello'
      try:
          int(s1)
      except IndexError as e:
          print(e)
      except KeyError as e:
          print(e)
      except ValueError as e:
          print(e)
      except Exception as e:
          print(e)

 

 

    2. 不常用的异常处理 :

      try :

      except :

      else :     (会在try 中没有异常时执行)

    

    示例 :

      print('start')

      try:

       1/0

      except  Exception:

          print ('炸了'!)

      else:

        print('else 执行了')

      print('end...')

 

      

      try:

      except:

      finally:    (无论异常是否发生,最终都会执行 (要放到最后一个) )

 

 

    示例 :

      print('start')

      try:

       1/0

      except  Exception:

          print ('炸了'!)

      else:

        print('else 执行了')

      finally:

        print('finally  执行了')

      print('end...')

 

    使用 finally 来回收资源

      try:

        f = open('a.txt','rt',encoding='utf-8')

        f.read()

        f.write('123')

      except  Exception:

        print ('发生异常了')

      finally:

        print('关闭文件')

        f.close()

 

 

  6. 主动抛出异常 :

    当程序中有一些限制,然而用户没有遵守,那我们可以主动抛出异常.

    语法. : raise 异常对象(异常的详细信息)

       类型必须是BaseException的子类

 

    示例:

      age = input('请输入整型的年龄')

      if not age。isdigit():

        raise  TypeError ('你输入的不是整型')

      age = int(age)

      print ('十年后你%s岁'%(age+10))

      (有些用户就不输入整型,所以会导致程序爆炸.这就要用到raise了)

      

 

  7.  断言 :

    断言可以理解为, 断定, 就是很清楚,很明确

    什么时候需要断言 ?

      下面的代码必须依赖上面代码的正确数据

    语法 :  assert  结果为bool的表达式

      如果值为True 则继续往下执行

      如果值为False  抛出异常 AssertionError  表示断言失败

    没有assert  也可以使用if 来用.  assert仅仅是省略了代码

    

 

    示例:

      #第一部分代码. 负责产生一个列表

      li = []

      li.append(1)

      li.append(2)

      # 这里一定要确保数据是有效的

      

      # 第一种解决方式, 用抛出异常 raise

      if  len(li)  <  1:

        raise  ValueError('列表中没有数据')

 

      # 第二种解决方式, 断言  assert

      assert  len(li)  >  0

      

      # 需要使用列表中的数据来完成任务. 如果没有数据就无法完成

      print(li[0])

      print(li[0])

      print(li[0])

 

 

  8. 自定义异常 :

    当系统提供的这些异常类型, 和你要描述的错误不匹配时,我们就需要自定义异常类型

    写法 :    

      class  : 自定义异常类型名称(BaseException):

    总结:

      之所以自定义异常类型,是为了更具体的描述你的错误,让使用者一眼就可以看出来

    关键点:

      1. 如何自定义异常类型

      2.  在except中, 使用as 来获取异常对象, as可以给异常类型起别名,而且把异常类型的值赋给后面

        的别名.

 

    示例:

      #  你随便输入一句话, 看我喜不喜欢,  不喜欢我就抛出异常

      class unlikeError (BaseException):

        def  __init__(self,msg):

          self.msg = msg

 

      text = input('输入一段话')

      if text == '你真帅'

        print('你说的对')

      else:

        raise  UnlikeError('你再看看 ?')

 

 

 

  9 .异常处理的使用场景:

    

    有的同学会这么想, 学完了异常处理后,好强大, 我要为我的每一段程序都加上try...except. 干毛线去

    思考它会不会有逻辑错误啊, 这样就很好啊, 多省脑细胞啊.

    其实: 首先, try...except是你附加给你的程序的一种异常处理的逻辑. 与你的主要的工作是没有关系的

    这种东西加多了.会导致你的代码可读性变差,

    然后异常处理根本就不是你2b逻辑的擦屁股纸, 只有在错误发生的条件无法预知的情况下,才应该加上

    try...except..

 

 

 

三.  网络编程 初识

  .1. 为什么要学习网络编程 ? 

    前两次的项目: ATM购物车,和选课系统都是单机程序 , 写出来只能自己玩.

    但是我们以后进公司写的程序百分之99都是网络程序, 所以现在要学习网络编程.

 

  2.  应用软件的构架 :

    1. C / S

      client(客户端) ====  server(服务器)

    2. B / S

      browser(浏览器) ==== server

    

    互联网中处处是C/S架构

      如黄色网站是服务端,你的浏览器是客户端(B/S架构也是C/S架构的一种)

      腾讯作为服务端为你提供视频,你得下个腾讯视频客户端才能看它的视频)

    C/S架构与socket的关系:

      我们学习socket就是为了完成C/S架构的开发

 

 

    在不同的计算机上,  一个安装客户端,一个安装服务器,  它们要通过网络来通讯

  

    什么是网络通讯呢 ?

      利用互联网来连接上,用来通讯

    

    要完成通讯必须具备的条件 :

    1. 物理连接介质 ( 网线, WIFI, 光纤)

    2, 必须遵循相同的标准

     

    在计算机网络中,同样的需要具备这两个条件.

    作为一个应用软件开发者, 不需要关心第一步, 我们的重点是通讯的标准,(通讯的协议)

 

    网络协议 :

      OSI 七层模型.:  后来由于觉得表示层跟会话层又麻烦又没什么用, 就把它两个加入到了应用层.

        应用层

        表示层

        会话层

        传输层

        网络层

        数据链路层

        物理层

 

    物理层:

      物理层的由来 :

        上面提到,孤立的计算机之间要想一起玩, 就必须接入internet,言外之意就是

         计算机之间必须完成组网

      

      物理层的功能:

        主要是基于电器特性发送高低电压(电信号),高电压对应数字1. 低电压对应数字0

 

 

    数据链路层:

      数据链路层的由来: 

        单纯的电信号0和1没有任何意义,必须规定电信号多少一位一组,每组什么意思

      数据链路层的功能:

        定义了电信号的分组方式

    

    以太网协议:

      

      早期的时候各个公司都有自己的分组方式,后来形成了统一的标准,即以太网协议ethernet

      ethernet规定

      • 一组电信号构成一个数据报,叫做‘帧’
      • 每一数据帧分成:报头head和数据data两部分

 

    

      head包含:(固定18个字节)

      • 发送者/源地址,6个字节
      • 接收者/目标地址,6个字节
      • 数据类型,6个字节

      data包含:(最短46字节,最长1500字节)

      • 数据包的具体内容

      head长度+data长度=最短64字节,最长1518字节,超过最大限制就分片发送.

 

    mac 地址:

      head中包含的源和目标地址的由来 :  ethernet规定接入internet 的设备都必须具备网卡,发送端

      和接收端的地址便是指网卡的地址, 即mac地址

      

      mac地址 : 每块网卡出厂时都被烧制上一个世界唯一的mac地址, 长度为48位2进制, 通常由12位

      16进制数表示(前六位是厂商编号,后六位是流水线号)

 

    广播:

      有了mac地址, 同一网络内的两台主机就可以通信了 (遗爱主机通过arp协议获取另外一台主机的

      mac地址)  ethernet采用最原始的方式, 广播的方式进行通信, 即计算机通信基本靠吼.

      如果大家都有自己的喇叭都想广播,带宽就承受不住了.

      网络层会区分哪种人要广播, 哪种不要广播

 

 

    以太网协议 工作在数据链路层规定了, 数据报 (数据帧) 的格式, 以太网协议传输数据的方式是广播

    然而在网络非常庞大的时候, 使用广播的方式传输会造成资源的浪费, 造成网络瘫痪.

    由于以上的问题, 推出了新的协议.

    IP协议.

 

 

    网络层:

      

      网络层由来:

        有了ethernet、mac地址、广播的发送方式,世界上的计算机就可以彼此通信了,

        问题是世界范围的互联网是由一个个彼此隔离的小的局域网组成的,

        那么如果所有的通信都采用以太网的广播方式,那么一台机器发送的包全世界都会收到,

        这就不仅仅是效率低的问题了,这会是一种灾难

 

      网络层功能:

        引入一套新的地址用来区分不同的广播域 / 子网,这套地址即网络地址

      

      

    

      IP协议:

      • 规定网络地址的协议叫ip协议,它定义的地址称之为ip地址,广泛采用的v4版本即 ipv4,它规定网络地址由32位2进制表示
      • 范围0.0.0.0-255.255.255.255
      • 一个ip地址通常写成四段十进制数,例:172.16.10.1

      ip地址分成两部分

      • 网络部分:标识子网
      • 主机部分:标识主机

      注意:单纯的ip地址段只是标识了ip地址的种类,从网络部分或主机部分都无法辨识

      一个ip所处的子网.

      例:172.16.10.1与172.16.10.2并不能确定二者处于同一子网

 

    

      子网掩码

        所谓”子网掩码”,就是表示子网络特征的一个参数。它在形式上等同于IP地址,

        也是一个32位二进制数字,它的网络部分全部为1,主机部分全部为0。比如,

        IP地址172.16.10.1,如果已知网络部分是前24位,主机部分是后8位,那么子网络掩码就是

        11111111.11111111.11111111.00000000, 写成十进制就是255.255.255.0。

 

        知道”子网掩码”,我们就能判断,任意两个IP地址是否处在同一个子网络。

        方法是将两个IP地址与子网掩码分别进行AND运算(两个数位都为1,

        运算结果为1,否则为0),然后比较结果是否相同,如果是的话,

        就表明它们在同一个子网络中,否则就不是。

 

        比如,已知IP地址172.16.10.1和172.16.10.2的子网掩码都是255.255.255.0,

        请问它们是否在同一个子网络?两者与子网掩码分别进行AND运算,

        172.16.10.1:10101100.00010000.00001010.000000001

        255255.255.255.0:11111111.11111111.11111111.00000000

        AND运算得网络地址结果:10101100.00010000.00001010.000000001->172.16.10.0

 

        172.16.10.2:10101100.00010000.00001010.000000010

        255255.255.255.0:11111111.11111111.11111111.00000000

        AND运算得网络地址结果:10101100.00010000.00001010.000000001->172.16.10.0

        结果都是172.16.10.0,因此它们在同一个子网络。

        总结一下,IP协议的作用主要有两个,一个是为每一台计算机分配IP地址,

        另一个是确定哪些地址在同一个子网络。

 

 

      ip数据包

        ip数据包也分为head和data部分,无须为ip包定义单独的栏位,直接放入以太网包的data部分

 

        head:长度为20到60字节

        data:最长为65,515字节。

        而以太网数据包的”数据”部分,最长只有1500字节。因此,如果IP数据包超过了1500字节,

        它就需要分割成几个以太网数据包,分开发送了。

 

 

      ARP协议

        arp协议由来:计算机通信基本靠吼,即广播的方式,所有上层的包到最后都要封装上

        以太网头,然后通过以太网协议发送,在谈及以太网协议时候,我门了解到

        通信是基于mac的广播方式实现,计算机在发包时,获取自身的mac是容易的,

        如何获取目标主机的mac,就需要通过arp协议

        arp协议功能:广播的方式发送数据包,获取目标主机的mac地址

 

        协议工作方式:每台主机ip都是已知的

        例如:主机172.16.10.10/24访问172.16.10.11/24

        一:首先通过ip地址和子网掩码区分出自己所处的子网

        二:分析172.16.10.10/24与172.16.10.11/24处于同一网络(如果不是同一网络,

          那么下表中目标ip为172.16.10.1,通过arp获取的是网关的mac)

        三:这个包会以广播的方式在发送端所处的自网内传输,所有主机接收后拆开包,

          发现目标ip为自己的,就响应,返回自己的mac

 

 

  

转载于:https://www.cnblogs.com/lvyipin1/p/9892529.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值