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','123'

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. 常见问题说明
posted @ 2016-12-25 16:43  木上清明  阅读(195)  评论(0编辑  收藏  举报