函数

 

                                                                              函数基本内容

 if __name__=='__main__'的简单理解

 if __name__ == '__main__' 我们简单的理解就是: 如果模块是被直接运行的,则代码块被运行,如果模块是被导入的,则代码块不被运行。(不运行被导入模块里面的函数)

一、语法定义:

       def sayhi( ):   #()函数名

              逻辑值

              返回值

       sayhi()  #(调用函数名)

二、参数

          def calc (x,y)  #(x,y为形参)

          c = calc(5,6)   #(5,6传入函数内的就是实参)

( 1)默认参数:

         def calc(name,age,course,country = 'CN')   

          #(在不输入国籍的时候默认都为CN,如果输入则为其他的。默认参数都放在最后,如果以前不在最后变陈默认参数 后也在最后                                      

(2)关键参数:

          给函数传参数要按照顺序,不想按照顺序就可以传参数就可以用关键参数,在调用的时候指定参数名

           def calc(name,age,course,country = 'CN')

           calc ("yisa',course='py',age = 22)  (在没有标明是哪一个的参数名的时候不能改变顺序,且,关键参数必须放在最后的位置)

            最后的结果还是按照函数只管参数顺序出来的

(3)非固定参数:

           不确定用户有多少个参数要传入的时候 

           def calc (name,age,*arges)   #(多传入的参数会变成一个元祖)  (*arges 一般放在最后因为会把后面所用的值默认组成一个元祖

             print( name,age,arges)

           1)、calc ('yisa',22,'CN','py')

                   输出   yisa  22  ('CN','py')

          2)、calc ('yisa',22,['CN','py'])              calc ('yisa',22,*['CN','py'])     (加*号去掉元祖符号)

                    输出  yisa  22 (['CN','py'])             输出  yisa  22   ['CN','py']

           3)、 def calc (name,age,*arges,**kwargs)   **kwarge  (把传入的参数默认组成一个字典

                     calc ('yisa',22,'CN','py',sex='male',province = 'sichuan')

                     yisa  22 ('CN','py')  {'sex':'male','province' :'sichuan'}

 

三、返回值:

                 

                   1.return的作用:结束一个函数的执行

                 2.首先返回值可以是任意的数据类型。

                 3.函数可以有返回值:如果有返回值,必须要用变量接收才有效果

                 4.也可以没有返回值没有返回值,函数返回为None

                 

 1  def calc(x):
 2 
 3         a=111
 4         b=[1,2,3]
 5         c={'a':15,'b':6}
 8         if  ------              #(函数在执行过程中遇到return语句,就会停止执行并返回结果,后面的语句都不执行)
 9 
10            return a       #(未在函数中指定return,函数返回值为None)
11        else -----
12 
13            return  a,b,c   #(返回多个值,变量之间按照逗号隔开,以元祖的形式返回)

 

 

 

 四、 全局与局部变量

 

        name =  'Alex li'
        def c_name():
           global name     (定义了全局变量)
           name = ''alex'  
           print(name)

    

 五、 嵌套函数

              就是函数里面套函数

         def  name ()
             name=‘Alex’
             def   age()
                age= 22
                print(age)
            age()
        name()                   变量要由里往外找

 

 六、匿名函数

             calc = lambda x,y:x**y  (声明一个函数)

             map( func,data)     (函数,数据) 就是把data里面的数都付给函数,取算值

             res = map(lambda x:x**2,[1,2,3,4,5]

 

七、高阶函数

               一个函数可以接受另外一个函数作为参数

       def add(x,y,f)
            return  f(x)+f(y)    returen 是返回另外一个函数
       res = add(3,-6,abs)        abs(是绝对值的意思)

 

八、递归

               如果一个函数在内部调用函数本身,这个函数就是递归函数

                  必须有一个明确的结束条件

       def calc(n):
            v = int(n/2print(v)
            if v ==0
               renturn'done'
            calc(v)
           print(v)
 
     输出    5
            2
            1
            0
            1
            2
            5
           10

 

九、内置函数

                   只写一个不容易记得

                     zip   a=[1,2,3,4]

                      b=['a','b','c']     list(zip(a,b))   [(1,'a'),(2,’b'),(3,'c')]  一一对应多余的丢弃

 

 函数进阶

  一、名称空间

                    x=1 (名称空间就是存放名字x与1绑定关系的地方)

                  locals :是函数内的名称空间,包括局部变量和形参

                  globals: 全局变量

                   buitins:内置模块的名字空间

  二、闭包

   

           1.闭 :内部的函数 
   2.包 :包含了对外部函数作用域中变量的引用

          两个原则,开放封闭原则

          对扩展是开放的

          对修改是封闭的

1 def outer():
2      name='alex'   #(这里定义是给让内层函数一起使用)
3      def inner():
4             name='yisa'  #(如果这里再定义name,那么就不是一个闭包,只是嵌套函数)
5             print("在inner里打印外层函数变量;name)
6      return inner  (这里只是返回inner 的内存地址)
7 f= outer()
8 f()( 执行inner())
闭包解释

 

 

 

 三、装饰器

    

         装饰器的功能:在不修改原函数及其调用方式的情况下对原函数功能进行扩展

  装饰器的本质:就是一个闭包函数

 

 1 def login(auth_type):
 2             user_name = 'yisa'
 3             password = 'a123'
 4             global user_status
 5                         if user_status == False:
 6                 _user_name = input('Name:')
 7                 _password = input('Password:')
 8                 if _user_name == user_name and _password == password:
 9                     print("登陆成功")
10                     user_status = True
11                 else:
12                     print("wrong name or password")
13             if user_status ==True:
14                func()   #(这里通过了验证,就调用相应功能)
15 
16 @login
17 def home():    #(原函数不带参数的类型)
18     print("------首页--------")
19 def america():
20     print("-------欧美专区----")
21 
22 def japan():
23     print("--------日本专区-----")
24 
25 @login
26 def henan(style):     #(原函数第一个参数的类型)
27     print("--------河南专区------",style)
28 
29 
30   (1)   home()
31         #henan()
32         login(henan)   (用户之前只需要调用henan()  这里相当于改变了调用方式)这种方法不可取,因为每一个的调用方式都会改变
装饰器例子

 

 

 

       在调用前进行认证(qq\weixin)  那就只能在外面多定义一层函数   

 

 1 user_status = False
 2 def login(auth_type):
 3    def outer(func):
 4       def inner(*arge,**kwargs):
 5          if auth_type=="weixin"    #(这里还要验证一次登录方式)
 6             user_name = 'yisa'
 7             password = 'a123'
 8             global user_status
 9             if user_status == False:
10                 _user_name = input('Name:')
11                 _password = input('Password:')
12                 if _user_name == user_name and _password == password:
13                     print("登陆成功")
14                     user_status = True
15                 else:
16                     print("wrong name or password")
17             if user_status ==True:
18                 func(*arge,**kwargs)
19           else20              print('只能使用微信登录‘)
21         return inner
22     return outer
23 def home():
24     print("------首页--------")
25 def america():
26     print("-------欧美专区----")
27 @login('weixin')
28 def japan():
29     print("--------日本专区-----")
30              # @login #(这个功能和henan = login(henan)一样)这个就是装饰器  加了之后自动进入函数第一层
31              #@login('qq') #相当于退两层,先是login('qq'),然后是out('henan).  加了参数又自己进去下一层
32              # 一个login不加括号是return一层,带一个参数是两个return, 就是要定义三次去调用
33 def henan(style):
34     print("--------河南专区------",style)
35 # henan = login(henan)
36 henan('aaa')
37 japan()
调用前进行再次认证

 

 

 

 3.2 带参数的装饰

           带参数的装饰器:就是给装饰器传参

   用处:就是当加了很多装饰器的时候,现在忽然又不想加装饰器了,想把装饰器给去掉了,但是那么多的代码,一个一个的去闲的麻烦,那么,我们可以利用带参数的装饰器去装饰它,这就他就像一个开关一样,要的时候就调用了,不用的时候就去掉了。

     

 1 带参数的装饰器:(相当于开关)为了给装饰器传参
 2   # F=True#为True时就把装饰器给加上了
 3   F=False#为False时就把装饰器给去掉了
 4  def outer(flag):
 5       def wrapper(func):
 6           def inner(*args,**kwargs):
 7               if flag:
 8                   print('before')
 9                   ret=func(*args,**kwargs)
10                  print('after')
11              else:
12                  ret = func(*args, **kwargs)
13              return ret
14          return inner
15      return wrapper
16  
17  @outer(F)#@wrapper
18  def hahaha():
19      print('hahaha')
20  
21  @outer(F)
22  def shuangwaiwai():
23      print('shuangwaiwai')
24  
25  hahaha()
26  shuangwaiwai()
给装饰器传参

 

 

 

  3.3多个装饰器装饰一个函数

         

 1 def qqqxing(fun):
 2     def inner(*args,**kwargs):
 3         print('in qqxing: before')        #第一个执行
 4         ret = fun(*args,**kwargs)
 5         print('in qqxing: after')         #第五个执行
 6         return ret
 7     return inner
 8 
 9 def pipixia(fun):
10     def inner(*args,**kwargs):
11         print('in qqxing: before')        #第二个执行
12         ret = fun(*args,**kwargs)     #第三个执行
13         print('in qqxing: after')          #第四个执行
14         return ret
15     return inner
16 @qqqxing
17 @pipixia
18 def dapangxie():
19     print('饿了吗')
20 dapangxie()
21 
22 '''
23 @qqqxing和@pipixia的执行顺序:先执行qqqxing里面的 print('in qqxing: before'),然后跳到了pipixia里面的
24         print('in qqxing: before')
25         ret = fun(*args,**kwargs)
26         print('in qqxing: after'),完了又回到了qqqxing里面的 print('in qqxing: after')。所以就如下面的运行结果截图一样
27 '''
28 
29 多个装饰器装饰一个函数
多个装饰器装饰一个函数

 

 

 

 

 四、生成器和迭代器

       4.1列表生成器:(  只能写到列表、元祖,但不能是字典)

            a = [i+1  for i in range(10)]     把后面的  i  值赋给前面  (列表生成式)

               a = [i  if i <5 else i*i for i iin b]  这里的b 是字典、列表、字符串

      生成器:generator

         a = [i+1  for i in range(10)]   

          g = ( i+1 for i in range(10))把[ ]  改为(  )就创建了一个生成器

          可以通过next( )获得generator的一个返回值     

next()
  >>>  1
next()
>>> 2
next()        因为太麻烦了,所以我么基本不用next()来调用函数
>>>3

           因为一般用  for 循环

         如果推算的算法比较复杂,用for 循环不能实现时,还可以用函数来实现

          Fibonacci 函数  除了第一个和第二个数外,任意一个数可由前两个数相加的到。

 def  fib(max):     (max  表示多少位)
       n, a,b = 0,0,1
       while n <max :
                print(b)
                 a,b= b,a+b
                n = n+1

      fib 函数和generator 仅一步之遥   要把 fib 变成generator 只需要把print(b) 改为 yieldb

 1 def  fib(max):     (max  表示多少位)
 2        n, a,b = 0,0,1
 3        while n <max :
 4                 #print(b)
 5                 yield  b      (相当于函数停在了这里,程序也停在了这里(把函数的执行过程冻结在这一步,并且把b的值返回给外面的 next(),
 6                           next()唤醒冻结的函数,直到遇到下一个yield )
 7                  a,b= b,a+b
 8                 n = n+1
 9         return 'done'
10 
11       (1) print(    )
12              yield  b   (第一次到这里就停止了)
13        (2) print(   )
14             
15          第二次输出(2)的内容再输出(1)的内容 然后遇到yield 就再一次停止
16       send 的作用
17        1、唤醒函数并继续进行(如果函数有被yield 中止了,可以继续进行)
18        2、发送一个信息到生成器内部
yield应用

         4.2迭代器

                 可以用于for 循环的数据类型有以下几种:

                 1、数据集合:list  tuple dict  set str 

                 2、一类是生成器generator, 包括生成器带yield 的generator function

                    可直接用作于for循环额对象统称为可迭代对象:iterable

        可以使用isinstance()  判断一个对象是否是interable 对象

        生成器不但可以被用作for 循环,还可以被next()函数不断调用把那个返回下一个值,知道最后抛出stopinteration错误表示无法返回下一个值了

         可以被next()函数不断调用把那个返回下一个值的对象成为迭代器:interator  (生成器是迭代器的一种)

         生成器都是可迭代对象, 但list dict str 虽然都是可以迭代(interable)但是却不是迭代器(iterator)

         

          filter 过滤函数的使用

               例如:筛选出偶数

               date=[1,2,3,4,5,6,7,8]

                 def calc(n):

                       if n%2==0:

                      return True

               oushu=filter( calc,data)

 

 

 

 

 

 

 

 

 

 

 

 

  

posted @ 2019-04-15 11:41  郁三十  阅读(148)  评论(1)    收藏  举报