python会不会出4_python走起之第四话

本节大纲:

一:双层装饰器:

一个函数可以被多层装饰器进行装饰,函数渲染(编译)从下到上,函数执行从上到下。

如下程序:

1 #!/usr/bin/env python

2 #-*-coding:utf-8-*-

3 # author:liumeide

4

5 # USERINOF={'islogin':True}

6 USERINOF={'user_type':'2','islogin':True}

7 def login(func):

8 def inner_1(*args,**kwargs):

9 if USERINOF.get('islogin',None):

10 ret=func()

11 return ret

12 else:

13 print('login first!')

14 return inner_1

15 def check_user(func):

16 def inner(*args,**kwargs):

17 if USERINOF.get('islogin',None)==True and USERINOF.get('user_type',None)=='2':

18 ret=func()

19 return ret

20 else:

21 print('permission deny!!')

22 return inner

23 @login

24 @check_user

25 def index():

26 print('index')

27

28 index()

多层装饰器该如何理解呢?

上面的函数的可以执行顺序可以理解为:

首先:函数login、check_user、index加载到内存。在调用index函数的时候,执行index函数,因为index函数被check_user函数装饰,所以把check_user函数的内的inner函数体重新赋值给index,index函数体被当做

参数传入check_user函数。当满足inner函数的条件的时候被执行,新的函数index函数的函数体inner被login函数的所装饰,也就是说inner函数被重新赋值给inner_1函数。也就是说最后调用执行index()顺序:

先执行inner_1函数体----->在执行inner函数体-->在执行index原先的函数体。

多层装饰器以此类推,同样的原理。三层以上的装饰器很少使用。

二:字符串格式化:

%[(name)][flags][width].[precision]typecode

%号初始化字符串:

顺序传入参数。

执行名称传入参数

保留小数点后几位

当有占位符的时候 需要%%输出%如果没有占位符需要只写一个%在占位符的时候类似一个转义的意思。

1:

1 print('name:%s,age:%s'%('evil','22'))

2

3 name:evil,age:22

普通字符串的初始化,需要传入的实参和占位符的个数保持一致。

(name):按名字进行取值。

2:可以根据占位的name的key,根据后面的字典对应的value进行传入来进行传入实参。

1 print("Name:%(name)s"%{'name':'ok'})

2 Name:ok

3: flags一般和width宽度来一起配合使用,如果单纯的使用flags并没什么效果。很少使用这个功能。

1 print("qqqq%(name)+s"%{'name':'ok'})

2 qqqqok

2个一起配合使用:+10表示右对齐,字符串ok占用10个字符。右对齐;正数前加正好,负数前加负号

1 print("qqqq%(name)+10s"%{'name':'ok'})

2 qqqq ok

-号表示左对齐。左对齐;正数前无符号,负数前加负号;

空格    右对齐;正数前加空格,负数前加负号;

0        右对齐;正数前无符号,负数前加负号;用0填充空白处;

.precision   可选,小数点后保留的位数

但是没有居中的功能。

1 print("qqqq%(name)-10sqqq"%{'name':'ok'})

2 qqqqok qqq

print("%+10d" % 10)

+10

1 print("%-10d" %10)

2 10

1 print("%04d" % 5)

2 0005

1 print("%04d" % -5)

2 -005

1 print("% 4d" % 5)

2 5

1 print("%.2f" % 1.225)

2 1.23

typecode表示执行传入的字符串类型。有如下:

s,获取传入对象的__str__方法的返回值,并将其格式化到指定位置

r,获取传入对象的__repr__方法的返回值,并将其格式化到指定位置

c,整数:将数字转换成其unicode对应的值,10进制范围为 0 <= i <= 1114111(py27则只支持0-255);字符:将字符添加到指定位置

o,将整数转换成 八  进制表示,并将其格式化到指定位置

x,将整数转换成十六进制表示,并将其格式化到指定位置

d,将整数、浮点数转换成 十 进制表示,并将其格式化到指定位置

e,将整数、浮点数转换成科学计数法,并将其格式化到指定位置(小写e)

E,将整数、浮点数转换成科学计数法,并将其格式化到指定位置(大写E)

f, 将整数、浮点数转换成浮点数表示,并将其格式化到指定位置(默认保留小数点后6位)

F,同上

g,自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是e;)

G,自动调整将整数、浮点数转换成 浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是E;)

%,当字符串中存在格式化标志时,需要用 %%表示一个百分号

但是没有将整数转换成二进制功能。

1 print('%%%d'%5)

2 %5

1 print('------%c-----%o-------%x'%(65,15,15))

2 ------A-----17-------f

format函数初始化字符串:

[[fill]align][sign][#][0][width][,][.precision][type]

1 print('adad{0}adadada{0}dada{1}'.format(1,2))

2 adad1adadada1dada2

1 print('adad{name}adadada{age}'.format(name='OK',age=22))

2 adadOKadadada22

居中功能并用a填充宽度为10.

1 print('adad{name:a^10s}adadada{age}'.format(name='OK',age=22))

2 adadaaaaOKaaaaadadada22

左对齐<

1 print('adad{name:a<10s}adadada{age}'.format(name='OK',age=22))

2 adadOKaaaaaaaaadadada22

右对齐>

1 print('adad{name:a>10s}adadada{age}'.format(name='OK',age=22))

2 adadaaaaaaaaOKadadada22

转化百分比

print('this is {:%}'.format(0.2222))

this is 22.220000%

支持整数转化二进制输出:

1 print("---{0:d}----{0:b}---{0:o}--{1:%}".format(15,0.2))

2 ---15----1111---17--20.000000%

三:生成器和迭代器

具有生成一定条件数据的能力的对象叫做生成器。

具有取数据的能力叫做迭代器。

在进行处理大数据的时候,用生成器会降低内存的消耗,每一次取值生成一次,在下次取值的时候,内存会回收该值,避免了浪费内存。

其中filter函数和map函数返回的对象就是生成器。比如xrange函数返回的对象也是生成器。

1 a=[1,2,31,4]

2 f=filter(lambda a:a>3,a)

3

4 for i in f:

5 print(i)

6 print(f)

7 31

8 4

9

生成器本身由函数创造的,如何把普通的函数转成生成器呢?

如果函数体内包含关键字yield 时这个函数就是生成器。

1 def fun():

2 print(111)

3 yield 1

4 fun()

5 print(fun())

6

在调用函数的fun()时候并不执行函数。只有去取这个对象的时候进行生成。

1 def fun():

2 yield 1

3 yield 2

4 yield 3

5 fun()

6 for i in fun():

7 print('__%s'%i)

8 print(fun())

9 __1

10 __2

11 __3

12

当for循环执行时,执行函数体。第一次的时候,去函数func找yield 对应的值1 赋值给i输出,第二次从第一次的位置下一个的yield的值为2取值并赋值给i,直到取到所有的yield的结束循环。每一次取值生成对应的对象。

上面的函数fun是生成器而生成的结果fun()是迭代器,也就说对象具有可以被迭代,在迭代时候执行next方法取值,只能从前往后取值,

练习:基于生成器生成range功能。

1 def myrange(args):

2 st=0

3 while True:

4 if st >args:

5 return

6 yield st

7 st+=1

8 ret=myrange(9)

9 for i in ret:

10 print(i)

11 0

12 1

13 2

14 3

15 4

16 5

17 6

18 7

19 8

20 9

四:函数递归。执行本身的函数体,当满足一定条件退出,并把最后执行的结果返回给上个函数,如果没有条件限制会无限执行下去。

1 def fun(x):

2 x+=1

3 if x>3:

4 return 1

5 return fun(x)

6 t=fun(1)

7 print(t)

8 1

执行3次fun(x)函数。循环执行多次相同的函数体。

练习:实现累乘功能,比如输入3  实现3*2*1

1 def fun(x):

2 if x==1:

3 return 1

4 return x*fun(x-1)

5 print(fun(3))

6 6

五:模块

分类:内置模块、第三方模块、自定义模块。在python中叫模块其他语言叫类库。

使用模块:先import 导入后使用。

存在方式:.py文件。或者一个文件夹里有多个.py文件组成的一个模块。

自定义模块导入:

目录之间用.表示

如果同一级不通模块导入相同的方法该如何区分呢???

1:通过相对路径来区分

request模块调用上面的2个co模块。如果路径层级不多可以这么写 如果层级过多呢?调用次数过多呢?

1 import lib.co

2 import common.co

3 common.co.login()

4 lib.co.login()

5 common OK

6 lib OK

简单的方法 将导入的模块进行别名操作:

1 from lib import co as f1

2 from common import co as f2

3 f1.login()

4 f2.login()

5 lib OK

6 common OK

下面的方法是我们经常用的。

模块的意义:便于管理代码。不同的功能的代码进行归类。

模块导入的依据:

1 import sys

2 print(sys.path)

3 C:\python2\day6

4 C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\python35.zip

5 C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\DLLs

6 C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\lib

7 C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32

8 C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\lib\site-packages

sys.path是一个路径的列表。默认python 有限搜索当前py文件的目录依次搜索。所以当我们自定义模块时候可以有2种方式让python 找到我们定义的模块:

1:把自定义模块加入这个列表(append())

2:把自定义的模块加入上面的目录之中。

这样在导入模块的时候不会出现:ImportError: No module named 'xxx'

那怎么找出自己模块所在目录呢?

1 import os

2 print(os.path.abspath(__file__))

3 print(os.path.dirname(os.path.abspath(__file__)))

4 print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

5

6 C:\python2\day6\s2.py

7 C:\python2\day6

8 C:\python2

根据自己需求将自己的变量导入sys.path即可。

模块的名称:不要和系统的内置模块的名字冲突。

第三方模块:1:pip进行安装

2:源码进行安装。

安装第三方模块:requests

pip install requests

常用模块介绍:

json模块:

常用函数dums()、dum();loads()、load()

对于加s参数和不加s参数区别:

加s的是直接可以对python 的数据转换成json串(dums())或者直接将json串转换成python能识别的数据类型。而不加s的是将python的数据转换成json串并将json串写入文件中,或者将文件中的json串转换成python的基本数据。

1 data=[1,2,3,4,(1,2,True)]

2 obl=json.dumps(data)

3 with open('data.txt','w') as f1:

4 f1.write(obl)

5 [1, 2, 3, 4, [1, 2, true]]

如果需要写入需要操作文件才能写入。

1 data=[1,2,3,4,(1,2,True)]

2 obl=json.dumps(data)

3 t_load=json.loads(obl,encoding='utf8')

4 print(type(t_load),t_load)

5 [1, 2, 3, 4, [1, 2, True]]

在将python基本数据类型进行json转换的时候,会将python的一些数据类型或者相应的值进行转换,比如上面的python的元组转换json时候变为列表。True变为 true。

转换表如下:

跨语言平台常用该模块。该模块可以将python的基本数据类型(列表、字典)转换成字符串----序列化。也可以将字符串形式的python 类型字符创转换成对应的数据类型(列表、字典)--反序列化。

1 import json

2 list_1=[1,2,3,4,]

3 # json.dump(list_1,open('json.txt','w'))

4 obj=json.load(open('json.txt','r'))

5 print(obj)

6 [1, 2, 3, 4]

pickle模块:可以将非python数据类型的数据进行序列化和反序列化。存储方式是二进制。所以要以wb或者rb进行相关的dums和loads

1 import pickle

2 a='aa'

3 pickle.dump(bytes(a,encoding='utf-8'),open('pickle.txt','wb'))

pickle.dumps()将相应的数据类型转换成字节。如果不指定编码,python解释器会用默认编码进行处理。

1 import pickle

2 data=[1,2,3,4,(1,2,True)]

3 t=pickle.dumps(data)

4 print(t,type(t))

5 b'\x80\x03]q\x00(K\x01K\x02K\x03K\x04K\x01K\x02\x88\x87q\x01e.'

1 import pickle

2 a='aa'

3 # pickle.dump(bytes(a,encoding='utf-8'),open('pickle.txt','wb'))

4 t=pickle.load(open('pickle.txt','rb'))

5 s=str(t,encoding='utf-8')

6 print(s)

7 aa

import pickle

data=[1,2,3,4,(1,2,True)]

t=pickle.dumps(data)

t_load=pickle.loads(t)

print(t_load,type(t_load))

[1, 2, 3, 4, (1, 2, True)]

在Django中会用到经常用到pickle模块。

requests模块:属于第三方模块需要进行手动安装(pip  install requests)

进入python安装目录:E:\python3.6\Scripts

运行:pip.exe install request

import requests

import json

res=requests.get("http://wthrcdn.etouch.cn/weather_mini?city=北京")

res.encoding='utf-8'

print(type(res))

dict_1=json.loads(res.text)

print(dict_1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值