
本节内容
1.字符串格式化
2.迭代器和生成器
3.装饰器
4.Json & pickle 数据序列化
5.软件目录结构规范
一、字符串格式化
百分号式
%[(name)][flags][width].[precision]typecode
- (name) 可选,用于选择指定的key
- flags 可选,可供选择的值有:
- + 右对齐;正数前加正好,负数前加负号;
- - 左对齐;正数前无符号,负数前加负号;
- 空格 右对齐;正数前加空格,负数前加负号;
- 0 右对齐;正数前无符号,负数前加负号;用0填充空白处
- width 可选,占有宽度
- .precision 可选,小数点后保留的位数
- typecode 必选
- s,获取传入对象的__str__方法的返回值,并将其格式化到指定位置
- r,获取传入对象的__repr__方法的返回值,并将其格式化到指定位置
- c,整数:将数字转换成其unicode对应的值,10进制范围为 0 <= i <= 1114111(py27则只支持0-255);字符:将字符添加到指定位置
- o,将整数转换成 八 进制表示,并将其格式化到指定位置
- x,将整数转换成十六进制表示,并将其格式化到指定位置
- d,将整数、浮点数转换成 十 进制表示,并将其格式化到指定位置
- e,将整数、浮点数转换成科学计数法,并将其格式化到指定位置(小写e)
- E,将整数、浮点数转换成科学计数法,并将其格式化到指定位置(大写E)
- f, 将整数、浮点数转换成浮点数表示,并将其格式化到指定位置(默认保留小数点后6位)
- F,同上
常用格式化:
tpl = "i am %s" % "alex" tpl = "i am %s age %d" % ("alex", 18) tpl = "i am %(name)s age %(age)d" % {"name": "alex", "age": 18} tpl = "percent %.2f" % 99.97623 tpl = "i am %(pp).2f" % {"pp": 123.425556, } tpl = "i am %.2f %%" % {"pp": 123.425556, }
Format方式
tpl = "i am {}, age {}, {}".format("seven", 18, 'alex') tpl = "i am {}, age {}, {}".format(*["seven", 18, 'alex']) tpl = "i am {0}, age {1}, really {0}".format("seven", 18) tpl = "i am {0}, age {1}, really {0}".format(*["seven", 18]) tpl = "i am {name}, age {age}, really {name}".format(name="seven", age=18) tpl = "i am {name}, age {age}, really {name}".format(**{"name": "seven", "age": 18}) tpl = "i am {0[0]}, age {0[1]}, really {0[2]}".format([1, 2, 3], [11, 22, 33]) tpl = "i am {:s}, age {:d}, money {:f}".format("seven", 18, 88888.1) tpl = "i am {:s}, age {:d}".format(*["seven", 18]) tpl = "i am {name:s}, age {age:d}".format(name="seven", age=18) tpl = "i am {name:s}, age {age:d}".format(**{"name": "seven", "age": 18}) tpl = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2) tpl = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2) tpl = "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%}".format(15) tpl = "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%}".format(num=15)
常用格式化操作
更多格式化操作:https://docs.python.org/3/library/string.html
二、迭代器和生成器
迭代器
我们已经知道,可以直接作用于for
循环的数据类型有以下几种:
一类是集合数据类型,如list
、tuple
、dict
、set
、str
等;
一类是generator
,包括生成器和带yield
的generator function。
这些可以直接作用于for
循环的对象统称为可迭代对象:Iterable
。
可以使用isinstance()
判断一个对象是否是Iterable
对象:
>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False
而生成器不但可以作用于for
循环,还可以被next()
函数不断调用并返回下一个值,直到最后抛出StopIteration
错误表示无法继续返回下一个值了。
*可以被next()
函数调用并不断返回下一个值的对象称为迭代器:Iterator
。
可以使用isinstance()
判断一个对象是否是Iterator
对象:
>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False
生成器都是Iterator
对象,但list
、dict
、str
虽然是Iterable
,却不是Iterator
。
把list
、dict
、str
等Iterable
变成Iterator
可以使用iter()
函数:
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
生成器
一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator);如果函数中包含yield语法,那这个函数就会变成生成器;
def func():
yield 1
yield 2
yield 3
ret = func()
for i in ret:
print(i)
上述代码中:func是函数称为生成器,当执行此函数func()时会得到一个迭代器。
>>> temp = func()
>>> temp.__next__()
1
>>> temp.__next__()
2
>>> temp.__next__()
3
>>> temp.__next__()
4
>>> temp.__next__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
实例
利用生成器自定义range
def nrange(num):
temp = -1
while True:
temp = temp + 1
if temp >= num:
return
else:
yield temp
小结
凡是可作用于for
循环的对象都是Iterable
类型;
凡是可作用于next()
函数的对象都是Iterator
类型,它们表示一个惰性计算的序列;
集合数据类型如list
、dict
、str
等是Iterable
但不是Iterator
,不过可以通过iter()
函数获得一个Iterator
对象。
Python的for
循环本质上就是通过不断调用next()
函数实现的,例如:
for x in [1, 2, 3, 4, 5]:
pass
实际上完全等价于:
# 首先获得Iterator对象:
it = iter([1, 2, 3, 4, 5])
# 循环:
while True:
try:
# 获得下一个值:
x = next(it)
except StopIteration:
# 遇到StopIteration就退出循环
break
三、装饰器
#!/usr/env python
# -*- coding:utf-8 -*-
#Version:Python3.4 # 定义函数,为调用,函数内部不执行
# 函数名 >> 代指这个函数体 def outer(func):
def inner(a):
print("log")
r = func(a)
print("befor")
return r
return inner @outer # @ + 函数名 功能:1、自动执行 outer 函数,并且将其下边的函数名f1当作参数传递
def f1(arg): # 2、将outer函数的返回值,重新赋值给 f1
print(arg)
return "砍你" @outer
def f2():
print("F2") @outer
def f100():
print("F100") ret = f1("小明")
print(ret)
#!/usr/env python
# -*- coding:utf-8 -*-
#Version:Python3.4 user,passwd = 'xiaoming','' def auth(auth_type):
def outer_wrapper(func):
def wrapper(*args,**kwargs):
username = input("Username:").strip()
password = input("Passowrd:").strip() if auth_type == "local":
if user == username and passwd == password:
print("\033[32;1mUser has passwd auth\033[0m")
res = func(*args,**kwargs)
print("砍刀哥")
return res
else:
exit("\033[31;1m密码不正确\033[0m")
elif auth_type == "ldap":
print("搞毛线ldap!")
return wrapper
return outer_wrapper def index():
pass @auth(auth_type="local")
def home():
print("wclecome to home page")
return "kandaoke" @auth(auth_type="ldap")
def bbs():
print("wclecome to bbs page") home()
bbs()
带参数的装饰器
四、Json & pickle 数据序列化
- json 用于【字符串】和 【python基本数据类型】 间进行转换
- pickle 用于【python特有的类型】 和 【python基本数据类型】间进行转换
Json模块提供了四个功能:dumps、dump、loads、load
pickle模块提供了四个功能:dumps、dump、loads、load
import pickle data = {"k1":123,"k2":"hello"} # pickle.dumps 将数据通过特殊的形式转换为只有python语言认识的字符串
p_str = pickle.dumps(data)
print(p_str) # pickle.dump 将数据通过特殊形式转换为只有python语言认识的字符串,并写入文件
# pickle存储方式默认是二进制方式
with open("test.txt","wb") as f:
pickle.dump(data,f) import json
# json.dumps 将数据通过特殊形式转换为所有程序语言都认识的字符串
j_str = json.dumps(data)
print(j_str) # json.dump 将数据通过特殊形式转换为所有程序语言都认识的字符串,
# 并写入文件
with open("test1.txt","w") as fp:
json.dump(data,fp)
五、软件目录规范
目录组织方式
假设你的项目名为foo, 我比较建议的最方便快捷目录结构这样就足够了:
Foo/
|-- bin/
| |-- foo
|
|-- foo/
| |-- tests/
| | |-- __init__.py
| | |-- test_main.py
| |
| |-- __init__.py
| |-- main.py
|
|-- docs/
| |-- conf.py
| |-- abc.rst
|
|-- setup.py
|-- requirements.txt
|-- README
简要解释一下:
-
bin/
: 存放项目的一些可执行文件,当然你可以起名script/
之类的也行。 -
foo/
: 存放项目的所有源代码。(1) 源代码中的所有模块、包都应该放在此目录。不要置于顶层目录。(2) 其子目录tests/
存放单元测试代码; (3) 程序的入口最好命名为main.py
。 -
docs/
: 存放一些文档。 -
setup.py
: 安装、部署、打包的脚本。 -
requirements.txt
: 存放软件依赖的外部Python包列表。 -
README
: 项目说明文件。
关于README的内容
目的是能简要描述该项目的信息,让读者快速了解这个项目。
它需要说明以下几个事项:
- 软件定位,软件的基本功能。
- 运行代码的方法: 安装环境、启动命令等。
- 简要的使用说明。
- 代码目录结构说明,更详细点可以说明软件的基本原理。
- 常见问题说明