zoukankan      html  css  js  c++  java
  • Python初识

    一、装饰器(decorator)

      1.定义:本质是函数(装饰其它函数),就是为了其它函数添加附加功能。

      2.原则:一是不能修改被装饰函数的源代码;二是不能修改被装饰函数的调用方式。

      3.装饰器包含的知识点:

          <1>函数(可作为变量)

          <2>高阶函数

            a.把一个函数名当作实参传给另一个函数(在不修改被装饰函数的情况下,为其添加新功能)

            b.返回值中包含函数名(不修改函数的调用方式)

           <3>嵌套函数

        高阶函数 + 嵌套函数  ==》 装饰器

      4.下面举例分析:

        <1>把一个函数名当作实参传给另一个函数 

            
     1 import time
     2 #把一个函数名当作实参传给另一个函数
     3 def hyt():
     4     time.sleep(3)  #延迟三秒
     5     print('This is hyt')
     6 
     7 def congcong(func):   #函数作为变量
     8     str_time = time.time() #记录开始时间
     9     func()    #运行hyt函数
    10     stop_time = time.time() #记录结束时间
    11     print('The func runs time is %s '%(stop_time-str_time)) #输出:The func runs time is 3.000171661376953
    12 
    13 congcong(hyt)
    View Code

          

         <2>返回值中包含函数名     

            
    import time
    #返回值中包含函数名(不修改函数的调用方式)
    def hyt():
        time.sleep(3)  #延迟三秒
        print('This is hyt')
    
    def cc(func):
        print(func)#打印hyt函数的内存地址,结果:<function hyt at 0x00206780>
        return func #返回hyt函数的内存地址
    hyt=cc(hyt)   #cc(hyt)表示传递hyt函数的内存地址,而cc(hyt())表示传递hyt函数的返回值,不符合高阶函数的定义
    hyt()   #运行hyt函数
    View Code

         <3>嵌套函数
        
            
    1 def foo():
    2    # '嵌套函数:在一个函数的函数体内部用def声明并调用另一个函数。'
    3     print('This is foo')
    4     def func():     #局部起作用,故只能在函数体内部调用
    5         print('This is func')
    6 
    7     func()
    8 foo()
    View Code

          

         <4>#局部作用域与全局作用域的访问顺序

     

       5.装饰器实际运用

        <1>简单点的:    

        

          
     1 def timer(func):    #timer(cc1) func = cc1
     2     'decorator(装饰器高潮版)'
     3     def hyt(*args,**kwargs):  #非固定传参,前者接受位置参数,后者接受关键字参数
     4         star_time = time.time() #time.time()调用时间的计时功能
     5         func(*args,**kwargs)  #run cc1()
     6         stop_time = time.time()
     7         print('The func running time is %s'%(stop_time-star_time))
     8     return hyt
     9 @timer      #等同于cc1 = timer(cc1)
    10 def cc1():
    11     time.sleep(1)
    12     print('This is cc1..')
    13 cc1()
    14 
    15 @timer      #等同于cc2 = timer(cc2) = hyt  cc2()=>hyt() ==> cc2(name,age)==>hyt(name.age)
    16 def cc2(name,age):
    17     time.sleep(3)
    18     print('Name is 33[32;1m{s1}33[0m,Age is 33[31;1m{s2}33[0m'.format(s1=name,s2=age))
    19 cc2('SC',20)
    View Code

         <2>复杂点的:

        

          
     1 #装饰器经典款
     2 import time
     3 user = 'cc'
     4 passwd = '123456'
     5 def auth(func):
     6     def wrapper(*args,**kwargs):
     7         usename = input('Usename:').strip()
     8         password = input('Password:').strip()
     9         if user == usename and passwd == password:
    10             print('Welcome 33[32;1m%s hased passed authentication33[0m'%(usename))
    11             func(*args,**kwargs)
    12         else:
    13             exit('33[31;1m Your usename or password is invalid33[0m')
    14     return wrapper
    15 
    16 def index():
    17     print('Welcome index page')
    18 @auth
    19 def home():
    20     print('Welcome home page')
    21 @auth
    22 def bbs():
    23     print('Welcome bbs page')
    24 index()
    25 home()
    26 bbs()
    27 '''
    28 
    29 #装饰器限量版
    30 import time
    31 user,passwd = 'cc','123456'
    32 def auth(auth_type):
    33     print('Auth type:',auth_type)
    34     #按照登录方式的不同而选择不同的认证方式
    35     def out_wrapper(func):
    36         def wrapper(*args,**kwargs):
    37             usename = input('Usename:').strip()
    38             password = input('Password:').strip()
    39             if auth_type == 'local':
    40                 if user == usename and passwd == password:
    41                     print('33[32;1mWelcome %s hased passed authentication33[0m'%(usename))
    42                     res_home = func(*args,**kwargs)# from home
    43                     print('---after authentication---')
    44                 else:
    45                     exit('33[31;1m Your usename or password is invalid33[0m')
    46             else:
    47                 print('There is no ladp.....')
    48         return wrapper
    49     return out_wrapper
    50 
    51 def index():
    52     print('Welcome index page')
    53 
    54 @auth(auth_type='local') #home = home(out_wrapper) => wrapper => home()=>wrapper()
    55 def home():
    56     print('Welcome home page')
    57     return 'from home'
    58 
    59 @auth(auth_type='ldap')
    60 def bbs():
    61     print('Welcome bbs page')
    62 index()
    63 home()
    64 bbs()
    View Code

    二、生成器(generator)

      1.定义:
         
          通过列表生成式。可以直接创建一个列表。但是受到内存限制,列表容量有限。而且,创建一个包含上百万    个元素的列表,
    那后面绝大多数元素占用的空间都白白浪费了。所以,如果列表可以按照某种算法推算出来,那    我们可以在循环的过程中不断推算后续的元素,这样就不必创建完整的list,从而节省大量的空间。在python中,   这种一边循环一边计算的机制,称为生成器:generator。

      2.生成器创建方法及实例
        <1>最简单的生成方法
    把列表生成式的[]改成(),就创建了一个生成器(generator)。

        <2>列表生成式和生成器实例:
        
            
     1 #列表生成式(简洁)
     2 
     3 a = [i*2 for i in range(8)]
     4 print(a)    #输出结果:[0, 2, 4, 6, 8, 10, 12, 14]
     5 
     6 
     7 #传统的列表生成方式
     8 
     9 a = []
    10 for i in range(8):
    11     a.append(i*2)
    12 print(a) #输出结果:[0, 2, 4, 6, 8, 10, 12, 14]
    View Code(列表生成式)
            
    1 L = [x * x for x in range(8)]  #列表(list)
    2 print(L) #输出:[0, 1, 4, 9, 16, 25, 36, 49]
    3 M = (x * x for x in range(8))  #生成器(generator)
    4 print(M) #输出:<generator object <genexpr> at 0x00537F00>
    5 print(M.__next__()) #输出:0  生成器的_next_()方法
    6 print(M.__next__()) #输出:1
    7 print(M.__next__()) #输出:4
    View Code(生成器)
        <3>生成器的调用和迭代
          注意:
    生成器(generator)保存的是算法,每次调用_next_(),就计算出M的下一个元素的值,直到计算到最      后一个元素,没有更多元素时,抛出StopIteration(异常)的错误。但这种方法太过繁琐,创建generator后,     基本不会使用_next_(),正确方法是使用for循环来迭代它,并且不需要关心StopIteration的错误  
       
            
    1 N = (y*2 for y in range(6))
    2 for i in N:
    3     print(i) #输出:0 2 4 6 8 10
    View Code
    
    

             

        <4>斐波拉契数列和异常处理
          
    generator很强大,但如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以使用    函数来实现。比如著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数可有前两个数相加得    到:1,1,2,3,5,8,13,...斐波拉契数列用列表生成式写不出来,但可用函数轻松表示出来 
       
            
     1 def fib(max):  #max = 10
     2     n ,a,b = 0,0,1
     3     while n < max:
     4         #print(b)
     5         yield  b #yield 表示出产,产生,保存了函数的中断状态
     6         a,b = b,a+b # t = (b,a+b) 是一个元组,a=t[0],b=t[1]
     7         n = n + 1
     8     return 'worked down' #异常的时候打印return的内容
     9 #fib(10) #输出:1,1,2,3,5,8,13,21,34,55
    10 print(fib(max)) #输出:<generator object fib at 0x00507E70>
    11 
    12 '''
    13 f = fib(10)
    14 print(f.__next__())#输出:1
    15 print(f.__next__())#输出:1
    16 print(f.__next__())#输出:2
    17 print('Hello everyone,now looping') #可以插在生成器其中不影响其连续过程
    18 for i in f:
    19     print(i)#输出:3,5,8,13,21,34,55
    20 '''
    21 #异常处理
    22 g = fib(6)
    23 while True:
    24     try: #未出错的时候执行
    25         x = next(g)  #next为内置方法,等同于_next_()方法
    26         print('g:',x)   #输出:g: 1   1   2   3   5   8
    27     except StopIteration as e: #出错时捕获错误定义为e
    28         print('Generator return value:',e.value) #输出Generator return value: worked down
    29         break
    View Code
      3.关于生成器并行运算
      
        
     1 import time
     2 def consumer(name):
     3     print('33[32;1m%s33[0m 准备吃饭了'%name)
     4     while True:
     5         shuijiao = yield   #yield 接受来自N的send 方法传来的参数
     6         print('33[31;1m[%s]33[0m 饺子煮好了,被33[32;1m%s33[0m吃完了'%(shuijiao,name))
     7 
     8 N = consumer('hyt')
     9 N.__next__() #此方法只调用,不传值,输出:hyt 准备吃饭了
    10 N.__next__() #输出:[None] 饺子煮好了,被hyt吃完了
    11 b1,b2 = '猪肉馅','牛肉馅'
    12 N.send(b1) #send方法调用并传值,输出:[猪肉馅] 饺子煮好了,被hyt吃完了
    13 N.send(b2) #输出:[牛肉馅] 饺子煮好了,被hyt吃完了
    14 
    15 def prodouct(name):
    16     c1 = consumer('sc')
    17     c2 = consumer('cc')
    18     c1.__next__()
    19     c2.__next__()
    20     print('33[32;1m%s 开始做饺子了!33[0m'%name)
    21     for i in range(3):
    22         time.sleep(2)
    23         print('两人平分一碗饺子')
    24         c1.send('粉丝')
    25         c2.send('韭菜')
    26 prodouct('congcong')
    View Code
    
    

    三、迭代器

      1.可迭代对象(Iterable)

        <1>定义:
         可以直接作用于for循环的数据类型有以下几种:
        一类 是集合数据类型,如list、tuple、dict、set、str等
        二类 是generator,包括生成器和带yield的generator function.
        这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
        
        <2>判断方法
    可以使用isinstance()判断一个对象是否有Iterable对象。
        <3>实例:
            
    1 from collections import Iterable
    2 print(isinstance([],Iterable)) #判断列表是否有可迭代对象 True
    3 print(isinstance((),Iterable))  #判断字典是否有可迭代对象 True
    4 print(isinstance({},Iterable))  #判断集合是否有可迭代对象  True
    5 print(isinstance('huangyuting',Iterable))   #判断字符串是否有可迭代对象  True
    6 print(isinstance(666,Iterable)) #判断数字是否有可迭代对象  False
    7 print(isinstance((x for x in range(4)),Iterable)) #判断generator是否有可迭代对象  True
    View Code

          注意:而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,

          直到最后抛出StopIteration错误表示无法继续返回下一个值了。

      2.迭代器(Iterator)

        <1>定义:可以被next函数调用并不断返回下一个值的对象称为迭代器:Iterator。

        <2>判断方法:可以使用isinstance()判断一个对象是否是迭代器(Iterator)对象。

        <3>实例:    

          
    1 from collections import Iterator
    2 print(isinstance((),Iterator))   #判断字典是否是迭代器  False
    3 print(isinstance([],Iterator))  #判断列表是否是迭代器  False
    4 print(isinstance({},Iterator))  #判断集合是否是迭代器  False
    5 print(isinstance('congcong',Iterator))  #判断字符串是否是迭代器  False
    6 print(isinstance(888,Iterator))  #判断数字是否是迭代器  False
    7 print(isinstance((x for x in range(5)),Iterator))  #判断生成器是否是迭代器  True
    View Code
    
    

          <4> 可迭代对象转成迭代器的方法:

            由上可知,生成器都是迭代器,然而list,dict,str虽然都是可迭代对象(Iterable),但不是

          迭代器(Iterator),可以把list,dict,str等Iterable变成Iterator可以使用iter()函数。如下

          所示:     

            
    1 from collections import Iterator
    2 print(isinstance(iter([]),Iterator),type(iter([])))    #True <class 'list_iterator'>
    3 print(isinstance(iter(()),Iterator),type(iter(())))    #True <class 'tuple_iterator'>
    4 print(isinstance(iter({}),Iterator),type(iter({})))    #True <class 'dict_keyiterator'>
    5 print(isinstance(iter('hytsc'),Iterator),type(iter('hytsc')))   #True <class 'str_iterator'>
    View Code

      3.一点疑问解答: 为什么list,dict,str等数据类型不是迭代器(Iterator)?

        因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopItration错误。可以将这个数据流看成一个有序序列,但我们却不能提前知道序列的长度,只有不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

        Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
    
    
     4. Python的for循环本质上就是通过不断调用next()函数实现的,
      例如:
      
        
     1 for x in range(5):
     2     print(x)
     3 #等价于
     4 t = iter(range(5)) #首先获得Iterator对象
     5 #print(dir(t)) #打印 t 可调用的所有方法
     6 while True: #循环
     7     try:
     8         x = next(t) #获取下一个值
     9     except StopIteration: #遇到StopIteration就退出循环
    10         break
    View Code
    四、python内置函数大揭秘:
      
         
     1 print(all([1,0,4])) #所有数据为真(非零即为真),空表也为假 输出:False
     2 print(any((0,-1,4))) #任意数据为真 输出:True
     3 print(bin(10)) #将十进制转为二进制 输出:0b1010
     4 print(hex(10))#将十进制转为十六进制 输出:0xa
     5 print(oct(8))#将十进制转为八进制 输出:0o10
     6 print(bool([])) #判断真假(非零即为真),输出:False
     7 
     8 a = bytes('abcde',encoding='utf-8')
     9 print(a)    #输出:b'abcde'
    10 b = bytearray('abcde',encoding='utf-8')
    11 print(b)    #输出:bytearray(b'abcde')
    12 b[0] = 65  #此处只能输入ASCII码值,A为97
    13 print(b)    #输出:bytearray(b'Abcde')
    14 
    15 a = 'hello'
    16 print(a.capitalize(),a) #字符串不能修改,只能重新生成新的,输出:Hello hello
    17 
    18 def func():
    19     pass
    20 print(callable(func)) #判断是否可调用
    21 
    22 print(chr(97)) #打印ASCII码对应的字符,输出;a
    23 print(ord('a')) #打印字符a对应的ASCII码值,输出;97
    24 
    25 code = '''
    26 def fib(max):
    27     n,a,b = 0,0,1
    28     while n < max:
    29         #print(b)
    30         yield  b
    31         a,b = b,a+b
    32         n = n + 1
    33     return 'worked down'
    34 #fib(10)
    35 #异常处理
    36 g = fib(10)
    37 while True:
    38     try: #未出错的时候执行
    39         x = next(g)  #next为内置方法,等同于_next_()方法
    40         print('g:',x)   #输出:g: 1   1   2   3   5   8
    41     except StopIteration as e: #出错时捕获错误定义为e
    42         print('Generator return value:',e.value) #输出Generator return value: worked down
    43         break
    44 '''
    45 exec(code) #将字符串编译成一段可执行文件
    46 #py_obj = compile(code,"fib.log","exec") #将字符串编译成指定文件名的可执行代码
    47 #exec(py_obj)
    48 
    49 print(dir(code)) #打印 字符串code的所有方法
    50 print(divmod(9,2)) #求两个数的商和余数,并打印出来,输出:(4, 1)
    51 
    52 h = "['hello','world']"
    53 print(eval(h))  #将字符串转成字典或列表
    54 
    55 calc = lambda n:n**2
    56 print(calc(3))
    57 calc = lambda n:4 if n<3 else n #lambda为匿名函数
    58 print(calc(2)) #输出:4
    59 
    60 res = filter(lambda x:(x%2==1),range(10)) #从列表中筛选0到100以内的奇数
    61 for i in res:
    62     print(i) #输出:1,3,5,7,9
    63 
    64 res1 = map(lambda y:y*2,range(4))#将列表中元素全部处理
    65 res2 = [lambda d:d*d for d in range(2)]
    66 for i in res1:
    67     print(i)#输出:0,2,4,6
    68 for i in res2:
    69     print(i)#输出:<function <listcomp>.<lambda> at 0x006BE4F8>
    70             #      <function <listcomp>.<lambda> at 0x002EE300>
    71 
    72 import functools  #functools意为函数工具
    73 res3 = functools.reduce(lambda a,b:a*b ,range(1,6))#求列表1到6的阶乘,a接收a*b的值,b接收列表中的值
    74 print(res3)
    View Code(待续)
    
    

        

       
     1 a = frozenset([1,2,3,5,6,8]) #frozenset函数修饰后为不可变列表,集合
     2 
     3 print(globals()) #打印所在模块当前最大命名空间内的变量名和值(key-value)
     4 print(hash('cc'))#哈希函数,建立字符串等于数字的特定位置关系,输出:1362460451
     5 
     6 def test():
     7     local_test = 666 #局部变量
     8     print(locals())#返回局部变量,输出:{'local_test': 666} 打印所在模块当前最小命名空间内的变量名和值
     9     print(globals())#不包含local_test
    10 test()
    11 b = 999
    12 print(globals()) #只打印全局变量,不打印局部变量
    13 print(globals().get('local_test')) #输出:None
    14 
    15 print(pow(2,4)) #表示求 2 的 4 次方 输出:16
    16 
    17 print(round(3.14159,2)) #表示将3.14159保留两位小数
    18 '''
    19 a = {'b':5,'a':1,'d':4,'c':8}
    20 print(sorted(a.items())) #输出:[('a', 1), ('b', 5), ('c', 8), ('d', 4)],默认以key排序
    21 print(sorted(a.items(),key=lambda x:x[1] ))#输出:[('a', 1), ('d', 4), ('b', 5), ('c', 8)],指定以value排序
    22 
    23 d = [1,3,5,7]
    24 e = ['h','e','l','l','o']
    25 for i in zip(d,e):  #zip取最短的列表进行一一对应
    26     print(i)    #输出:(1, 'h') (3, 'e') (5, 'l') (7, 'l')
    27 
    28 __import__('生成器') #导入字符串
    View Code(完结)
    五、序列化与反序列化
      <1>序列化(json、pickle)
        
     1 #序列化:将内存对象转换成字符串保存起来
     2 '''import json
     3 info = {
     4     'name':'cc',
     5     'age':20,
     6     'job':'student'
     7 }
     8 f = open('test.txt','w',encoding='utf-8')
     9 #f.write(str(info))#很low的方法
    10 print(json.dumps(info),type(json.dumps(info)))#输出:{"age": 20, "job": "student", "name": "cc"} <class 'str'>
    11 f.write(json.dumps(info)) #专业方法
    12 f.close()
    13 '''
    14 #json 与 pickle 的区别在于:pickle只能在python中使用,而json却可以在各个语言间转换
    15 
    16 #pickle
    17 import pickle
    18 def hey(name):
    19     print('hello',name)
    20 
    21 info2 = {
    22     'name':'hyt',
    23     'age':18,
    24     'func':hey
    25 }
    26 f = open('test2.txt','wb')
    27 print(pickle.dump(info2,f))#输出:None
    28 pickle.dump(info2,f) #与 f.write(pickle.dumps(info)) 作用相同
    29 f.close()
    View Code
    
    

       

       <2>反序列化(json、pickle)    

        
     1 import json
     2 f = open('test.txt','r')
     3 #很low的方法
     4 data = f.read()
     5 f.close()
     6 print(data,type(data)) #输出:{'age': 20, 'job': 'student', 'name': 'cc'} <class 'str'>
     7 print(eval(data),type(eval(data))) #eval()是内置函数,可将字符串转为字典或列表,
     8                                 #输出:{'name': 'cc', 'age': 20, 'job': 'student'} <class 'dict'
     9 #专业的方法
    10 data = json.loads(f.read())
    11 print(data,type(data))#输出:{'job': 'student', 'age': 20, 'name': 'cc'} <class 'dict'>
    12 print(data['name'])#输出:cc
    13 '''
    14 
    15 #pickle
    16 import pickle
    17 def hey(name):
    18     print('hello',name)
    19 info2 = {
    20     'name':'hyt',
    21     'age':18,
    22     'func':hey
    23 }
    24 f = open('test2.txt','rb')
    25 data = pickle.load(f)# data = pickle.loads(f.read())
    26 print(data,type(data)) #输出:{'age': 18, 'name': 'hyt', 'func': <function hey at 0x0094E468>} <class 'dict'>
    27 print(data['func']('hyt'))
    28 f.close()
    View Code
    
    

                                                                                                                                                            

     

         
    
    


    
    
     



    
    
    
    


  • 相关阅读:
    第八周课程总结&实验报告(六)
    第七周课程总结&实验报告(五)
    第六周实验总结&学习总结
    关于我
    各种公告

    笔记 综合
    多项式全家桶
    FFT,NTT 笔记
    省选复习
  • 原文地址:https://www.cnblogs.com/schut/p/7430729.html
Copyright © 2011-2022 走看看