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


                                                                                                                                                        

 

     




 







原文地址:https://www.cnblogs.com/schut/p/7430729.html