本篇涉及内容

双层装饰器
字符串格式化

双层装饰器

装饰器基础请点我

有时候一个功能需要有2次认证的时候就需要用到双层装饰器了,下面我们来通过一个案例详细介绍一下双层装饰器:

  • 执行顺序:自上而下

  • 解释顺序:自下而上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
案例需求:
有三个功能,登录、显示首页、显示后台管理页面,显示首页需要登录才能够显示,显示后台管理页面也需要登陆,并且还需要具有管理员权限才可以显示管理页面,下面使用双层装饰器来实现显示后台管理页面的功能
   
   
# 存放用户信息
USER_INFO = {
    "is_login": False,
    "is_admin": False,
}
   
   
def check_login(func):
    """
    检查用户是否登录
    :param func: 被检测函数名
    :return: inner   返回内层函数inner函数名
    """
    def inner():
        if USER_INFO.get("is_login"):
            func()
        else:
            print("请登录")
    return inner
   
   
def check_admin(func):
    """
    验证是否有管理员权限
    :param func: 被检测函数名
    :return: inner 返回内层函数inner函数名
    """
    def inner():
        if USER_INFO.get("is_admin"):
            ret = func()
        else:
            print("没有管理员权限")
    return inner
   
   
# 当调用管理员后台页面的时候需要调用装饰器,先验证是否登录,然后在验证是否具有管理员权限
@check_login
@check_admin
def admin_page():
    """
    管理员后台页面
    :return:
    """
    print("admin_page")
   
   
@check_login
def home():
    """
    登录之后的首页
    :return:
    """
    print("home")
   
   
def login():
    """
    登录模块
    假如这里有两个账号,分别使用这两个用户登录看结果
        账号:a        密码:123      普通用户
        账号:admin    密码: admin   管理员用户
    :return:
    """
    user = input("请输入用户名:")
    pwd = input("请输入密码:")
    if user == "a" and pwd == "123":
        USER_INFO["is_login"] = True
    elif user == "admin" and pwd == "123":
        USER_INFO["is_login"] = True
        USER_INFO["is_admin"] = True
   
   
def main():
    while True:
        inp = input("1、登录   2、查看首页   3、查看后台管理页面\n>>")
        if inp == "1":
            login()
        elif inp == "2":
            home()
        elif inp == "3":
            admin_page()
   
   
if __name__ == '__main__':
    main()

字符串格式化

Python的字符串格式化有两种方式: 百分号方式、format方式

百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存。

1、百分号方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
%[(name)][flags][width].[precision]typecode     # 中括号内的都为可选项,typecode为必选项
   
    · (name)      可选,用于选择指定的key
    · flags       可选,可供选择的值有:
    · +           右对齐;正数前加正好,负数前加负号;
    · -           左对齐;正数前无符号,负数前加负号;
    · 空格        右对齐;正数前加空格,负数前加负号;
    · 0           右对齐;正数前无符号,负数前加负号;用0填充空白处
    · width       可选,占有宽度
    · .precision  可选,小数点后保留的位数
    · %           当字符串中存在格式化标志时,需要用 %%表示一个百分号
       
    · typecode    必选(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;)
  
注:Python中百分号格式化是不存在自动将整数转换成二进制表示的方式

常用格式化例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
s = "i am %s" % "zhangsan"
print(s)
 
# 输出
i am zhangsan
 
 
s = "i am %s age %d" % ("zhangsan", 10)
print(s)
 
# 输出
i am zhangsan age 10
 
 
s = "i am %(name)s age %(age)d" % {"name": "zhangsan", "age": 10}
print(s)
 
# 输出
i am zhangsan age 10
 
 
s = "percent %.2f" % 9.999      # 四舍五入
print(s)
 
# 输出
percent 10.00
 
 
s = "π is %(p).2f" % {"p": 3.1415926}
print(s)
 
# 输出
π is 3.14
 
 
s = "π is %(p).2f %%" % {"p": 3.1415926}    # 想使用百分号当做字符串输出时,需要使用两个百分号
print(s)
 
# 输出
π is 3.14 %

2、format方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[[fill]align][sign][#][0][width][,][.precision][type]
 
 
    fill           【可选】空白处填充的字符
    align          【可选】对齐方式(需配合width使用)
        <           内容左对齐
        >           内容右对齐(默认)
        =          内容右对齐,将符号放置在填充字符的左侧,且只对数字类型有效。 即使:符号+填充物+数字
        ^           内容居中
         
    sign           【可选】有无符号数字
        +           正号加正,负号加负;
        -          正号不变,负号加负;
        空格        正号空格,负号加负;
         
    #              【可选】对于二进制、八进制、十六进制,如果加上#,会显示 0b/0o/0x,否则不显示
    ,             【可选】为数字添加分隔符,如:1,000,000
    width          【可选】格式化位所占宽度
    .precision     【可选】小数位保留精度
     
    type           【可选】格式化类型
        # 传入” 字符串类型 “的参数
            s       格式化字符串类型数据
            空白    未指定类型,则默认是None,同s
             
        # 传入“ 整数类型 ”的参数
            b       将10进制整数自动转换成2进制表示然后格式化
            c       将10进制整数自动转换为其对应的unicode字符
            d       十进制整数
            o       将10进制整数自动转换成8进制表示然后格式化;
            x       将10进制整数自动转换成16进制表示然后格式化(小写x)
            X       将10进制整数自动转换成16进制表示然后格式化(大写X)
         
        # 传入“ 浮点型或小数类型 ”的参数
            e       转换为科学计数法(小写e)表示,然后格式化;
            E       转换为科学计数法(大写E)表示,然后格式化;
            f       转换为浮点型(默认小数点后保留6位)表示,然后格式化;
            F       转换为浮点型(默认小数点后保留6位)表示,然后格式化;
            g       自动在e和f中切换
            G       自动在E和F中切换
            %       显示百分比(默认显示小数点后6位)

常用格式化例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
s = "i am {}, age {}, {}".format("zhangsan", 18, "lisi")
print(s)
 
# 输出
i am zhangsan, age 18, lisi
 
 
s = "i am {}, age {}, {}".format(*["zhangsan", 18, 'lisi'])
print(s)
 
# 输出
i am zhangsan, age 18, lisi
 
 
s = "i am {0}, age {1}, really {0}".format("zhangsan", 18)
print(s)
 
# 输出
i am zhangsan, age 18, really zhangsan
 
 
s = "i am {0}, age {1}, really {0}".format(*["zhangsan", 18])
print(s)
 
# 输出
i am zhangsan, age 18, really zhangsan
 
 
s = "i am {name}, age {age}, really {name}".format(name="zhangsan", age=18)
print(s)
 
# 输出
i am zhangsan, age 18, really zhangsan
 
 
s = "i am {name}, age {age}, really {name}".format(**{"name": "zhangsan", "age": 18})
print(s)
 
# 输出
i am zhangsan, age 18, really zhangsan
 
 
s = "i am {0[0]}, age {0[1]}, really {0[2]}".format([1, 2, 3], [11, 22, 33])
print(s)
 
# 输出
i am 1, age 2, really 3
 
 
s = "i am {:s}, age {:d}, money {:f}".format("zhangsan", 18, 88888.1)
print(s)
 
# 输出
i am zhangsan, age 18, money 88888.100000
 
 
s = "i am {:s}, age {:d}".format(*["zhangsan", 18])
print(s)
 
# 输出
i am zhangsan, age 18
 
s = "i am {name:s}, age {age:d}".format(name="zhangsan", age=18)
print(s)
 
# 输出
i am zhangsan, age 18
 
s = "i am {name:s}, age {age:d}".format(**{"name": "zhangsan", "age": 18})
print(s)
 
# 输出
i am zhangsan, age 18
 
 
s = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
print(s)
 
# 输出
numbers: 1111,17,15,f,F, 1587.623000%
 
 
s = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
print(s)
 
# 输出
numbers: 1111,17,15,f,F, 1587.623000%
 
 
s = "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%}".format(15)
print(s)
 
# 输出
numbers: 1111,17,15,f,F, 1587.623000%
 
 
s = "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%}".format(num=15)
print(s)
 
# 输出
numbers: 1111,17,15,f,F, 1587.623000%

更多格式化操作狂点我

python学习之路-5 基础进阶篇的更多相关文章

  1. python学习之路-day2-pyth基础2

    一.        模块初识 Python的强大之处在于他有非常丰富和强大的标准库和第三方库,第三方库存放位置:site-packages sys模块简介 导入模块 import sys 3 sys模 ...

  2. Python学习之路-Day2-Python基础2

    Python学习之路第二天 学习内容: 1.模块初识 2.pyc是什么 3.python数据类型 4.数据运算 5.bytes/str之别 6.列表 7.元组 8.字典 9.字符串常用操作 1.模块初 ...

  3. Python学习之路-Day1-Python基础

    学习python的过程: 在茫茫的编程语言中我选择了python,因为感觉python很强大,能用到很多领域.我自己也学过一些编程语言,比如:C,java,php,html,css等.但是我感觉自己都 ...

  4. Python学习之路-Day2-Python基础3

    Python学习之路第三天 学习内容: 1.文件操作 2.字符转编码操作 3.函数介绍 4.递归 5.函数式编程 1.文件操作 打印到屏幕 最简单的输出方法是用print语句,你可以给它传递零个或多个 ...

  5. python学习第十六天 --继承进阶篇

    这一章节主要讲解面向对象高级编程->继承进阶篇,包括类多继承介绍和继承经典类和新式类属性的查找顺序不同之处. 多继承 上一章节我们讲到继承,子类继承父类,可以拥有父类的属性和方法,也可以进行扩展 ...

  6. python学习之路-day1-python基础1

    本节内容: Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入 模块初识 .pyc是个什么鬼? 数据类型初识 数据运算 表达式if ...else ...

  7. PYTHON学习之路_PYTHON基础(1)

    学习内容: 1.Python介绍 2.Python程序初接触和变量 3.Python用户交互 4.Python数据类型 5.Python循环if...(elif)...else 6.Python循环w ...

  8. PYTHON学习之路_PYTHON基础(10)

    学习内容: Python进程与线程 1.线程及线程类 2.线程守护 3.线程等待 4.线程锁 5.信号量 6.timer用法 7.队列 8.事件驱动 9.生产者消费者模型 10.进程及进程同步 11. ...

  9. PYTHON学习之路_PYTHON基础(8)

    学习内容: Python模块介绍 1.经典类 or 新式类 2.抽象接口 3.静态方法.类方法.属性方法 4.反射 5.异常处理 6.socket编程初识 7.用socket实现get.put文件等功 ...

随机推荐

  1. Hive MapJoin

    摘要 MapJoin是Hive的一种优化操作,其适用于小表JOIN大表的场景,由于表的JOIN操作是在Map端且在内存进行的,所以其并不需要启动Reduce任务也就不需要经过shuffle阶段,从而能 ...

  2. 再看ADO对象模型

    在敲学生管理系统之前,我们就学习过ADO的有关知识.但是昨天被问到ADO的几个对象,顿时无言!为什么会出现这样的结果呢,明明是学习过了,而且也实践过(红皮书的五个例子).这充分说明了,在以往的学习过程 ...

  3. IIS PHP 配置 问题总结

    今天帮助朋友解决一个IIS配置PHP的问题.大概是这样子的. IIS 与 PHP配置好了之后不能訪问,出现例如以下错误: HTTP 错误 500.19 - Internal Server Error ...

  4. Android 编程下的计时器

    在安卓 APP 的手机号注册逻辑中,经常会有将激活码发送到手机的环节,这个环节中绝大多数的应用考虑到网络延迟或服务器压力以及短信服务商的延迟等原因,会给用户提供一个重新获取激活码的按钮.如下图所示: ...

  5. Angular单页应用&AngularJS内部实现原理

    回顾 自定义指令 登录后获取登录信息session 首先在登录验证的时候保存一个user 在学生管理页面中运用ajax调用获取到登录的用户信息 对注销按钮添加点击事件:调用ajax在表现层给user赋 ...

  6. Java中的try/catch/finally

    样例1: public class Test{ public static String output = ""; public static void foo(int i){ t ...

  7. 最短路径floy算法———模板

    #include<cstdio>int n,i[1000][1000];int main(){ scanf("%d",&n); for (int a=1;a&l ...

  8. About USB Data Link Cable API

    About USB Data Link Cable API The text on this webpage is licensed under the Creative Commons Attrib ...

  9. hdu5338 ZZX and Permutations(贪心、线段树)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud ZZX and Permutations Time Limit: 6000/300 ...

  10. Window7下手动编译最新版的PCL库

    PCL简介 PCL是Point Cloud Library的缩写,是一个用于处理二维图像,三维深度图像和三维点云的C++库.该库是完全开源的,可免费用于商业和学术研究. 官方网站:http://poi ...