欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

我在黑马程序员培训的第二十一天

程序员文章站 2022-07-07 23:18:20
...
  • 闭包

    • 定义:在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们把这个使用外部函数变量的内部函数称为闭包

    • 特点:

      1.嵌套定义

      2.外层函数返回内层函数的引用

      3.内层函数可以使用外层函数提供的变量<*变量 环境变量 继承>

    • 示例代码:

      def func(num1):
      	print("in func")
      	def func_in(num2):
      		print("in func_in %d"%(num1+num2))
      	return func_in
      	
      	
      f=func(99)
      f(1)
      
    • def name(num1):
          def say(num2):
              print("%s说:%s"%(num1,num2))
          return say
      
      f=name('哪吒')
      f('我命由我不由天')
      
    • 修改*(外部)变量:

      先 声明*变量(外部函数提供给内部函数的值),不能和全局变量混淆:nonlocal xxx

      • 注意:可变类型不用声明;不可变类型 需要使用 nonlocal

      • 示例代码

        def func(num1):
            print("in func")
        
            def func_in(num2):
                nonlocal num1
                num1 += 1
                print("in func_in %d" % (num1 + num2))
        
            return func_in
        
        
        f = func(99)
        f(1)
        
  • 装饰器:在不修改代码的情况下对函数的功能进行扩展

  • 装饰器格式:

    def 外层函数(原函数引用):
    	def 内层函数():
            扩展功能
            原函数引用()
            扩展功能
        return 内层函数
    
    @外层函数
    def 函数名();
    	pass
    # 函数名 = 外城函数(函数名)
    
    def check(f):
    	def inner():
    		print("正在做安全检查")
    		f()
    	return inner
    	
    @check
    def login():
    	print("正在登录")
    # 灵魂代码 login = check(login)
    login()
    
    #	@check = login=check(login)
    #说白了:就是我想给自己买个帽子带上,但是我不想自己去买,就让别人买来帽子在给我带上
    #其中 login = check(login)
    #login 就相当于让别人去拿帽子
    #check(login) 还是原来的我自己
    #然后 让别人先把帽子放好,在把我叫过来,这样帽子就带上了.
    
  • 统计函数执行时间的装饰器

    import time
    
    def gettime(f):
        def inner():
            begin = time.time()
            f()
            end = time.time()
            print("花费了%f 秒" % (end-begin))
    
        return inner
    
    @gettime
    def f1():
        time.sleep(2.3)
        print("in f1")
    # f1 = gettime(f1)
    
    @gettime
    def f2():
        for i in range(3):
            time.sleep(1)
            print("in f2")
    # f2=gettime(f2)
    
    f1()
    f2()
    
  • 通用装饰器

    import time
    
    def gettime(f):
        def inner(*args, **kwargs):
            """*args接收所有的位置参数 (1,) **kwargs接收所有的关键字参数{"n2":22}"""
            begin = time.time()
            # 暂存 原函数的返回值 在最后位置返回即可
            ret = f(*args, **kwargs)  # 拆包 f(1,n2=22)
            end = time.time()
            print("花费了%f 秒" % (end-begin))
            return ret
        return inner
    
    @gettime
    def f1(number1):
        time.sleep(2.3)
        print("in f1")
        return 1001
    # f1 = gettime(f1)
    
    @gettime
    def f2(n1,n2):
        for i in range(3):
            time.sleep(1)
            print("in f2")
    # f2=gettime(f2)
    
    print(f1(1))
    f2(1, n2=22)
    
    • 装饰器工厂函数

      装饰器只能接受一个参数,如果希望装饰器内部代码能够根据参数 实现不一样的逻辑 那么 需要将装饰器函数放到一个外部函数中 由外部函数接收参数 装饰器可以直接使用

      import time
      
      """给装饰器传入更多参数目的: 希望装饰器内部代码能够根据参数 实现不一样的逻辑
          但是  装饰器只能接收一个参数
          解决方法: 将装饰器函数放到一个外部函数中 由外部函数接收参数 装饰器可以直接使用
      """
      def get_run_time(flag):
          def gettime(f):
              def inner(*args, **kwargs):
                  """*args接收所有的位置参数 (1,) **kwargs接收所有的关键字参数{"n2":22}"""
                  begin = time.time()
                  # 暂存 原函数的返回值 在最后位置返回即可
                  ret = f(*args, **kwargs)  # 拆包 f(1,n2=22)
                  end = time.time()
                  if flag == 0:
                      print("花费了%d 秒" % int(end - begin))
                  else:
                      print("花费了%f 秒" % (end-begin))
                  return ret
              return inner
          return gettime
      
      
      @get_run_time(1)
      def f1(number1):
          time.sleep(2.3)
          print("in f1")
          return 1001
      
      # 1 执行 get_time = get_run_time(1)   2 @gettime 开始对下面函数进行装饰
      # 一步理解  f1 = get_run_time(1)(f1)
      
      
      print(f1(1))
      

正则表达式

  • re模块:

    import re
    
    # match 匹配re.match(r"图片规则","网页数据")
    # 参数1是正则  参数2是数据  从头开始匹配
    #返回值是一个匹配结果的对象  匹配失败是 None;
    res = re.match(r"hello","helloworld")
    #search 搜索 参数返回值和match 完全一样 功能:从头开始搜索  并且尝试匹配
    res = re.search(r"hello","1helloworld")
    if res is None:
        print("匹配失败")
    else:
        print("成功:%s"%res.group())
    
    • #匹配一个任意字符(默认除\n)
      res = re.match(r"hello.","hello123")
      
      #让.只匹配点字符
      
        res = re.match(r"hello\.","hello.")
      
      #在re.S 模式下.可以匹配任意字符(包括\n)
      
        res = re.match(r"hello.","hello\n",re.S)
      
  • [ ]匹配其中任意一个字符

    • - res = re.match(r"hello[123]","hello1")
      
      - res = re.match(r"hello[0-9]","hello1")
      等价于:res = re.match(r"hello\d","hello1")
      如果不想取数字:
      - res = re.match(r"hello\D","hello1")
          
      - res = re.match(r"hello[a-z]","hello1")
      - res = re.match(r"hello[^0-9]","hello1")
      - res = re.match(r"hello[a-zA-Z0-9_","hello1")
      
      word 单词字符  [\da-za-Z_0-9]=\w  
      python3 默认 UNICODE模式<可以匹配汉字>
        res = re.match(r"hello\w","hello1")
        res = re.match(r"hello\w","hello后",re.UNICODE)
        res = re.match(r"hello\w","hello后",re.ASCII)
      # \W 禁止匹配 [\da-za-Z_0-9]字符
      
      # [\r\n\v\t\f]=\s	[^\r\n\v\t\f]=\S
      res = re.match(r"hello\s","hello ")
      res = re.match(r"hello\S","hello\t")
      
    • {n}前面匹配n次

    #1.{n}前面匹配n次
    res =re.match(r"哪吒\d{11}号","哪吒11111111111号")
    #{m,n 前面匹配 m次到 n次}
    #{0,11}={,11}
    res =re.match(r"哪吒\d{1,11}号","哪吒11111111111号")
    #大于等于1次 +
    res =re.match(r"哪吒\d+号","哪吒1号")
    #大于等于0次 *
    res =re.match(r"哪吒\d*号","哪吒1号")
    #0<=n<=1 ? 
    res =re.match(r"哪吒\d?号","哪吒1号")
    
    
    • [^]取反 r"^正则" 以开始 match 自带^属性

    • & 以结尾

    • import re
      
      # [^] 取反  r"^正则" 以开始 match 自带^属性
      res = re.match(r"\w{6,16}@qq.com", "[email protected]")
      res = re.match(r"\w{6,16}@qq\.com", "[email protected]")
      res = re.match(r"^\w{6,16}@qq\.com$", "[email protected]")
      res = re.match(r"^\w{6,16}@qq\.com$", "[email protected]")
      res = re.search(r"^\w{6,16}@qq\.com$", "[email protected]")
      
      if res is not None:
          print("成功了%s" % res.group())
      else:
          print("失败了")
      
    • 分组操作

    • 分组目的:将部分数据从整体提取出来

    • 获取分组结果 匹配结果对象.group(分组编号).group(分组编号) 默认参数为0 代表正则整体匹配结果

    • # 分组引用: 希望将前面某个分组的数据 放到正则的后续位置继续匹配 \分组编号
      import re
      #分组创建
      res = re.match(r"(\d{3,4})-(\d{6,8})","010-12345678")
      #分组引用
      res = re.match(r"(\d{3,4})-(\d{6,8}) 010-12345678", "010-12345678 010-12345678")
      res = re.match(r"(\d{3,4})-(\d{6,8}) 020-12345678", "020-12345679 020-12345678")
      res = re.match(r"(\d{3,4})-(\d{6,8}) \1-\2", "020-12345679 020-12345678")
      
      if res is not None:
      # 获取分组结果  匹配结果对象.group(分组编号) 默认参数为0 代表正则整体匹配结果 
      print("成功了%s"%res.group())
      print("成功了%s"%res.group(0))
      print("成功了%s"%str(res.group(1,2)))
      # 用户自己创建分组标号从1开始
      else:
      print("失败了")