python之路:Day04 --- Python基础4

时间:2023-03-09 07:05:35
python之路:Day04 --- Python基础4

本节内容

  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循环的数据类型有以下几种:

  一类是集合数据类型,如listtupledictsetstr等;

  一类是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对象,但listdictstr虽然是Iterable,却不是Iterator

  把listdictstrIterable变成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类型,它们表示一个惰性计算的序列;

集合数据类型如listdictstr等是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

简要解释一下:

  1. bin/: 存放项目的一些可执行文件,当然你可以起名script/之类的也行。
  2. foo/: 存放项目的所有源代码。(1) 源代码中的所有模块、包都应该放在此目录。不要置于顶层目录。(2) 其子目录tests/存放单元测试代码; (3) 程序的入口最好命名为main.py
  3. docs/: 存放一些文档。
  4. setup.py: 安装、部署、打包的脚本。
  5. requirements.txt: 存放软件依赖的外部Python包列表。
  6. README: 项目说明文件。

关于README的内容

  目的是能简要描述该项目的信息,让读者快速了解这个项目。

  它需要说明以下几个事项:

  1. 软件定位,软件的基本功能。
  2. 运行代码的方法: 安装环境、启动命令等。
  3. 简要的使用说明。
  4. 代码目录结构说明,更详细点可以说明软件的基本原理。
  5. 常见问题说明