• 六.函数和类


    1.自定义函数

    •  给函数编写文档:
      def function(x):
          "This is function document test."  #注意这里没有加入#号,这是函数内的写作方式。
          pass
      #注意下面的语句是function而不是function()。前者表示函数本身,后者表示函数的使用。 print(function.__doc__) help(function)
    • 所有的函数都有返回值。函数return后什么都没有,或没有return,函数返回None。不要让None的返回值给你带来麻烦。

     2.函数参数

    • 函数参数中的中括号[]表示可选参数,可选参数通常都这么写,用的时候别带中括号。:
      • L.index(value [, start [, stop ] ] ),这里的中括号表示:start和stop是可选参数。
    • 编写代码时,为了确保参数的正确性。应该在参数输入不对时以显而易见的方式失败。为此,通常使用assert断言和raise异常。
    • 参数为不可变参数:string、数、tuple,函数不修改外部变量
      N=456
      def test(n):
          n=123
      test(N)  #这相当于函数内部变量先建立内存n=N,然后再处理n
      print(N) #456
    • 参数为可变参数:list、dict,函数修改。
      list1=[1,"a",2]
      def test(l1):
          l1.append(123)
      test(list1)  #由于是可变参数,l1=list1只是建立了指针,并没有为数据重新建立内存。
      print(list1) #[1, 'a', 2, 123]
    • 函数参数可以分为位置参数和关键字参数。

      • 位置参数具有顺序依赖性
      • 关键字参数若以keyword形式传递,可以打乱顺序。function(key2=...,key1=...)
    •  参数的收集,输入的参数以什么形式存放:
      #参数收集:*args以元组形式存放,**kwargs以字典形式存放
      def func(*args,**kwargs):
          print(args)
          print(kwargs)
      func(1,2,3,"a","b",key1="name",key2="age",key3="sex")
      #(1, 2, 3, 'a', 'b')
      #{'key1': 'name', 'key2': 'age', 'key3': 'sex'}
    •  参数的分配,如果不是一一对应的输入参数,而是输入一个整体,输入数据如何分配:

      #如果以序列形式分配,要加上*
      def test1(a,b,c,d):
          print(a,b,c,d)
      List1=[1,"a",2,"b"]
      Tuple1=(4,3,2,1)
      test1(*List1) #1 a 2 b
      test1(*Tuple1) #4 3 2 1
      
      #如果以字典形式分配,要加上**,且key相同
      def test2(m,n):
          print(m,n)
      Dict1={"m":"name","n":"age"}
      test2(**Dict1) #name age

    3.函数的作用域和嵌套:

    • global声明全局变量,nonlocal声明非全局的上一层变量:
      #以下例子只是说明问题 , 实际应用中务必慎用全局变量。
      x,y,z=1,2,3
      def testA():
          global x #全局变量,指向最外层
          x,y,z=10,20,30 #全局x重新赋值
          print("first:",x,y,z) # first: 10 20 30
          def testB():
              global y #指向最外层,不是上一层
              y+=10 #所以y不是上一层的10,而是最外部的2
              x=20 #第二层没有声明x,所以x是局部
              print("second:",x,y,z) # second: 20 12 30
              def testC():
                  nonlocal x
                  x+=10
                  global z
                  print("third:",x,y,z) # third: 30 12 3
              testC()
              print("second2:",x,y,z) # second2: 30 12 30
          testB()
      print(testA(),x,y,z) # None 10 12 3
    • 函数的嵌套:可以在函数中定义函数,注意嵌套时return的是函数的运行(带括号)还是函数本体(不带括号)
      def test1():
          def test2():
              print("test2 in test1")
          return test2() #返回的是函数test2()的运行
      test1() # test2 in test1
      
      def test3():
          def test4():
              print("test4 in test3")
          return test4 #返回的是函数test4的本体
      test3()() # test4 in test3,其中的test3()就相当于test4,所以需要加()才可以运行

    4.类变量和实例化变量:

    • 类分为类变量和实例化变量:
      class A:
          a=123                  #类变量
          def function(self):
              self.var1=456#实例化变量,self让各def彼此不独立,self指向某个实例:ca=A(),self指向的就是ca,同时无需提供self指向的参数。
              A.var2=456#在功能中定义类变量:实例化且调用此功能才有。
              var3=789           #在函数中定义变量
      ca=A()
      print(A.a) #123
      ca.function()
      print(A.a,A.var2) #123 456
      
      cb=A()
      print(cb.a,cb.var2) #123 456,由于类被改变,再次新的实例会有
    • 类操作和实例操作,实例中先扫描实例变量,后扫描类变量
      class TEST:
          test="ABC"
          pass
      #t.***为实例化操作
      #TEST.***为类操作
      t=TEST()
      t.test="DEF"  #实例化操作,单变量赋值等同于定义
      print(t.test) #DEF,先扫描到实例化结果
      del t.test    #删除了实例化结果
      print(t.test) #ABC,扫描到类变量
    • 类变量和实例变化更具体的操作:
      class TEST:
          a=123 #类变量
          CommonList=[]
          def __init__(self):
              TEST.var="ABC" #这表示,创建实例时,增加类变量TEST.var="ABC"
              TEST.a+=10
              self.mylist = []
      
      #print(TEST.a,TEST.var) #无法执行,因为没有增加进去
      
      A=TEST()
      B=TEST()
      print(TEST.a,A.a,B.a)
      print(TEST.var,A.var,B.var)
      
      TEST.var="abcdef"
      print(TEST.var,A.var,B.var)
      
      A.a=A.a+10 #单变量在赋值时,等于自定义语句
      print(A.a,B.a,TEST.a)
      
      #类中增加类变量
      TEST.b="ADD"
      print(TEST.b,A.b,B.b)
      
      #实例a中增加self.a变量
      A.a=456
      print(TEST.a,A.a,B.a) #实例中,先索引实例变量,再类变量
      
      #删除实例a中的self.a变量,但是依然有类变量a
      del A.a
      print(TEST.a,A.a,B.a)
      
      #mylist操作,实例操作
      A.mylist.append("MyA")
      B.mylist.append("MyB")
      print(A.mylist,B.mylist)
      
      #CommonList操作,直接操作。实例中并没有增加,而是对类列表的操作
      A.CommonList.append("add a")
      B.CommonList.append("add b")
      TEST.CommonList.append("add TEST")
      print(A.CommonList,B.CommonList,TEST.CommonList)
      
      #实例中增加列表
      A.NewList=[]
      A.NewList.append("NewListA")
      print(A.NewList)
      
      #实例中增加列表且与类列表同名
      A.CommonList=[]
      print(A.CommonList,B.CommonList,TEST.CommonList)
      del A.CommonList
      print(A.CommonList,B.CommonList,TEST.CommonList)
      类变量和实例变量
    • 函数或类带()表运行,不带()表它本身的代码:var=ABC() 不同于 var=ABC

    5.类中设置私有化变量

    • Python不同于C++,类中没有专门的public、private。
      • 若类中要有私有化成员:__双下划线打头,访问需要特殊化访问:
        class TEST:
            __var1=123 #双下划线设置了私有化,无法正常访问
        a=TEST()
        print(a._TEST__var1)  #以此方式才可以访问私有化
        print(TEST._TEST__var1) #同上
      • from module import * 不会导入一个下划线打头的名称

    6.lambda函数,快速的表达函数:

    • lambda表达式:lambda ...(输入)... : ...(输出)...
      #下面两句表达效果一样,都把函数关联到变量foo
      def foo(x):return x*x
      foo=lambda x:x*x

     7.装饰器

    # 装饰器:本质是函数,为给其他函数添加附加功能
    # 原则:1.不能修改被装饰函数的源代码
    #       2.不能修改被装饰函数的调用方式
    # 实现装饰器知识储备:
    # 1.函数即“变量”
    # 2.高阶函数
    #   a:把一个函数名当做实参传给另一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
    #   b:返回值中包含函数名(不修改函数的调用方式)
    # 3.嵌套函数
    # 高阶函数+嵌套函数=>装饰器
    
    import time
    def timmer(func):
        def warpper(*args,**kwargs):
            start_time=time.time()
            func()
            stop_time=time.time()
            print("the func run time is %s" %(stop_time-start_time))
        return warpper  #注意这里不是warpper()
    
    @timmer
    def test1():
        time.sleep(1)
        print("in the test1")
    test1()
  • 相关阅读:
    面向对象之三个基本特征(javaScript)
    webpack初探
    浅谈Promise
    Vue Mixin 与微信小程序 Mixins 应用
    C#入门基础语法知识点总结(变量、运算符、类型转换)
    C#入门基础语法知识点总结(.NET开发环境及代码编写规范)
    触发器练习三
    触发器练习二
    触发器练习一
    存储过程练习二
  • 原文地址:https://www.cnblogs.com/i201102053/p/10620770.html
Copyright © 2020-2023  润新知