第二模块闯关练习

 1. 请写出 “路飞学城alex” 分别用 utf-8 和 gbk 编码所占的位数
“路飞学城alex” utf8占16位字节,gbk 占12位字节。

2. python有哪几种数据类型,分别什么?哪些数据类型是有序的。
python有:字符串、列表、元组、集合、字典、布尔 六种类型 。 其中字典是无序的。集合中有字典就是无序集合。

 3. 列表和字典的pop方法有什么区别。
列表pop不指定参数就是删除最后一个元素,参数有索引就删除索引对应的元素。
字典pop需要指定参数key。 
 
   1. read,readline,readlines的区别。

read        读取整个文件

readline    读取下一行

readlines   读取整个文件到一个迭代器以供我们遍历(读取到一个list中,以供使用,比较方便)、


2. 执行f.write()之后,会立刻写入磁盘吗?不会的话,有几种方式能让其写入磁盘中?

当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用close()方法时,

操作系统才保证把没有写入的数据全部写入磁盘。忘记调用close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。所以,

还是用with语句来得保险:  

with open('/Users/michael/test.txt', 'w') as f: 

  • f.write('Hello, world!')
     


3. 简述内置函数globals() locals()的作用 (口述)
Python两个内置函数——locals 和globals


这两个函数主要提供,基于字典的访问局部和全局变量的方式。
在理解这两个函数时,首先来理解一下python中的名字空间概念。Python使用叫做名字空间的
东西来记录变量的轨迹。名字空间只是一个字典,它的键字就是变量名,字典的值就是那些变
量的值。实际上,名字空间可以象Python的字典一样进行访问


每个函数都有着自已的名字空间,叫做局部名字空间,它记录了函数的变量,包括函数的参数
和局部定义的变量。每个模块拥有它自已的名字空间,叫做全局名字空间,它记录了模块的变
量,包括函数、类、其它导入的模块、模块级的变量和常量。还有就是内置名字空间,任何模
块均可访问它,它存放着内置的函数和异常。


当一行代码要使用变量 x 的值时,Python会到所有可用的名字空间去查找变量,按照如下顺序:


1.局部名字空间 - 特指当前函数或类的方法。如果函数定义了一个局部变量 x,Python将使用
  这个变量,然后停止搜索。
2.全局名字空间 - 特指当前的模块。如果模块定义了一个名为 x 的变量,函数或类,Python
  将使用这个变量然后停止搜索。
3.内置名字空间 - 对每个模块都是全局的。作为最后的尝试,Python将假设 x 是内置函数或变量。


如果Python在这些名字空间找不到 x,它将放弃查找并引发一个 NameError 的异常,同时传递
There is no variable named 'x' 这样一条信息。
 
 4. 函数闭包 (口述)  
    创建一个闭包函数需要满足哪几点: 

闭包(closure)是函数式编程的重要的语法结构。闭包也是一种组织代码的结构,它同样提高了代码的可重复使用性。

如果在一个内嵌函数里,对在外部函数内(但不是在全局作用域)的变量进行引用,那么内嵌函数就被认为是闭包(closure)。

定义在外部函数内但由内部函数引用或者使用的变量称为自由变量。

总结一下,创建一个闭包必须满足以下几点:

  • 1. 必须有一个内嵌函数
  • 2. 内嵌函数必须引用外部函数中的变量
  • 3. 外部函数的返回值必须是内嵌函数
 
5、装饰器(口述)
 本质上是一个函数。作用是用来装饰另一个函数(即被装饰函数),给被装饰函数添加功能。
前提是不能改变被装饰函数的源代码和调用方式。这样的一个函数称之为装饰器。
 
 
生成器和迭代器的区别?
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

生成器都是Iterator对象,但listdictstr虽然是Iterable,却不是Iterator

listdictstrIterable变成Iterator可以使用iter()函数:

>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True

我们已经知道,可以直接作用于for循环的数据类型有以下几种:

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

一类是generator,包括生成器和带yield的generator function。

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

可以使用isinstance()判断一个对象是否是Iterable对象:

  1. 如下,每个小字典的name对应股票名字,shares对应多少股,price对应股票的价格

  2. portfolio = [
    {'name': 'IBM', 'shares': 100, 'price': 91.1},
    {'name': 'AAPL', 'shares': 50, 'price': 543.22},
    {'name': 'FB', 'shares': 200, 'price': 21.09},
    {'name': 'HPQ', 'shares': 35, 'price': 31.75},
    {'name': 'YHOO', 'shares': 45, 'price': 16.35},
    {'name': 'ACME', 'shares': 75, 'price': 115.65}
    ]
    

计算购买每支股票的总价

用filter过滤出,单价大于100的股票有哪些

portfolio = [
{'name': 'IBM', 'shares': 100, 'price': 91.1},
{'name': 'AAPL', 'shares': 50, 'price': 543.22},
{'name': 'FB', 'shares': 200, 'price': 21.09},
{'name': 'HPQ', 'shares': 35, 'price': 31.75},
{'name': 'YHOO', 'shares': 45, 'price': 16.35},
{'name': 'ACME', 'shares': 75, 'price': 115.65}
]

for por_name in portfolio:
print(por_name['name'],'的总价是%s'%(por_name['shares']*por_name['price']))
# print(list(filter(lambda x:x>=100,por_name['price'])))

f =list(filter(lambda x:x['price']>=100,portfolio))
print("股票大于100的有:",f)

2,有如下程序, 请给出两次调用show_num函数的执行结果,并说明为什么:

1
2
3
4
5
6
7
8
9
10
num = 20
 
   def show_num(x=num):
       print(x)
 
   show_num()
 
   num = 30
 
   show_num()

  如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象,相当于通过“传值’来传递对象,此时如果想改变这些变量的值,可以将这些变量申明为全局变量。

3,有列表 li = [‘alex‘, ‘egon‘, ‘smith‘, ‘pizza‘, ‘alen‘], 请以列表中每个元素的第二个字母倒序排序;

  #测试可以取得正确值并能显示成功

#print(sorted(list(map(lambda x:x[1:],li)),key= lambda x:x,reverse=True))
print(sorted(li,key=lambda x:x[1],reverse=True))

4,有名为poetry.txt的文件,其内容如下,请删除第三行;

1
2
3
4
5
6
7
昔人已乘黄鹤去,此地空余黄鹤楼。
 
黄鹤一去不复返,白云千载空悠悠。
 
晴川历历汉阳树,芳草萋萋鹦鹉洲。
 
日暮乡关何处是?烟波江上使人愁。
技术分享图片
# 4,有名为poetry.txt的文件,其内容如下,请删除第三行;
# 方法一:
# import os
# p = ‘poetry.txt‘
# file = open(p,‘r‘,encoding=‘utf-8‘)
# print(file)
# pnew = ‘%s.new‘%p
# filenew = open(pnew,‘w‘,encoding=‘utf-8‘)
# str1 = ‘晴川历历汉阳树,芳草萋萋鹦鹉洲。‘
# for i in file:
#     if str1 in i:
#         i = ‘‘
#         filenew.write(i)
#     else:
#         filenew.write(i)
# file.close()
# filenew.close()
# os.replace(pnew,p)
# 方法二:逐行读取文件
import os
f1=open(‘poetry.txt‘, ‘r‘,encoding=‘utf-8‘)
 
str=‘晴川历历汉阳树,芳草萋萋鹦鹉洲。‘
with open(‘poetry1.txt‘, ‘w‘, encoding=‘utf-8‘) as f2:
    ff1=‘poetry.txt‘
    ff2=‘poetry1.txt‘
    for line in f1:
        if str in line:
            line=‘‘
            f2.write(line)
 
        else:
            f2.write(line)
f1.close()
f2.close()
os.replace(ff2,ff1)
View Code

 

5,有名为username.txt的文件,其内容格式如下,写一个程序,判断该文件中是否存在"alex", 如果没有,则将字符串"alex"添加到该文件末尾,否则提示用户该用户已存在;

1
2
3
pizza
alex
egon

  

1
2
3
4
5
6
7
8
9
10
11
# 5,有名为username.txt的文件,其内容格式如下,写一个程序,
# 判断该文件中是否存在"alex", 如果没有,
# 则将字符串"alex"添加到该文件末尾,否则提示用户该用户已存在;
with open(‘username.txt‘,‘r+‘,encoding=‘utf-8‘) as f:
    str1 = ‘alexx‘
    = f.read()
    print(i)
    if str1 in i:
        print("the user already exist in")
    else:
        f.write(‘ alexx‘)

  

6,有名为user_info.txt的文件,其内容格式如下,写一个程序,删除id为100003的行;

1
2
3
pizza,100001
alex, 100002
egon, 100003
技术分享图片
# 6,有名为user_info.txt的文件,其内容格式如下,
# 写一个程序,删除id为100003的行;
import os
a = ‘user_info.txt‘
b = ‘user_info1.txt‘
with open(a,‘r‘,encoding=‘utf-8‘) as f:
    with open(b, ‘w‘, encoding=‘utf-8‘) as f2:
        for i in f:
            if ‘100003‘ in i:
                pass
            else:
                f2.write(i)
os.replace(b,a)
View Code

7,有名为user_info.txt的文件,其内容格式如下,写一个程序,将id为100002的用户名修改为alex li

1
2
3
pizza,100001
alex, 100002
egon, 100003
技术分享图片
# 7,有名为user_info.txt的文件,其内容格式如下,写一个程序,
# 将id为100002的用户名修改为alex li;
file = ‘user_info.txt‘
old_str = ‘100002‘
new_str = ‘alex, 100002‘
file_data=‘‘
with open(file,‘r‘,encoding=‘utf-8‘) as f1:
 
    for line in f1:
        if old_str in line:
            line =new_str
        file_data +=line
 
        with open(file,‘w‘,encoding=‘utf-8‘) as f1:
            f1.write(file_data)
View Code

8,什么是装饰器?,写一个计算每个程序执行时间的装饰器;

  

1
2
3
4
    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,
同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
    这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,
提供了额外的功能。

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
8,写一个计算每个程序执行时间的装饰器;
import time
def timer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        func(*args)
        stop_time = time.time()
        d_time = stop_time-start_time
        print(d_time)
    return wrapper
 
@timer
def sayhi():
    print("hello word")
 
sayhi()

  

9,lambda是什么?请说说你曾在什么场景下使用lambda?

1
2
3
4
5
lambda函数就是可以接受任意多个参数(包括可选参数)并且返回单个表达式值得函数
    好处:
        1.lambda函数比较轻便,即用即扔,适合完成只在一处使用的简单功能
        2.匿名函数,一般用来给filtermap这样的函数式编程服务
        3.作为回调函数,传递给某些应用,比如消息处理

  

10,请分别介绍文件操作中不同文件之间打开方式的区别

模式 含义
r 文本只读模式
rb 二进制模式 这种方法是用来传输或存储,不给人看的
r+ 读写模式,只要有r,那么文件必须存在
rb+ 二进制读写模式
w 只写模式,不能读,用w模式打开一个已经存在的文件,如果有内容会清空,重新写
wb 以二进制方式打开,只能写文件,如果不存在,则创建
w+ 读写模式,先读后写,只要有w,会清空原来的文件内容
wb+ 二进制写读模式
a 追加模式,也能写,在文件的末尾添加内容
ab 二进制追加模式
a+ 追加模式,如果文件不存在,则创建文件,如果存在,则在末尾追加
ab+ 追读写二进制模式,从文件顶部读取文件,从文件底部添加内容,不存在则创建

11,简述普通参数,指定参数,默认参数,动态参数的区别

1
2
3
4
5
普通参数:以正确的顺序传入函数,调用时数量必须和声明的一样
指定参数:参数和函数调用关系密切,函数调用使用关键字参数来确定传入的参数值,参数
                允许函数调用时参数的顺序和声明时不一致
默认参数:函数进行调用时,如果没有新的参数传入则默认的情况下,就调用默认参数
动态参数:个别函数能处理比当初声明时更多的参数,这些参数就动态参数

12,写函数,计算传入的字符串中数字,字母,空格,以及其他的个数

技术分享图片
def func(s):
    al_num =0
    space_num = 0
    digit_num = 0
    others_num = 0
    for i in s:
        if i.isdigit():
            digit_num +=1
        elif i.isspace():
            space_num +=1
        elif i.isalpha():
            al_num +=1
        else:
            others_num +=1
        return (al_num,space_num,digit_num,others_num)
 
result = func("asdsadjlk1212jdjakdk2  d d d d323233223下")
print(result)
result = func("  d d d d323233223下")
print(result)
View Code

13,写函数,判断用户传入的对象(字符串,列表,元组)长度是否大于5

技术分享图片
def func(s,lis,tup):
    zifuchuan = len(s)
    liebiao = len(lis)
    yuanzu = len(tup)
 
    if zifuchuan>5:
        print("大于5")
    else:
        print("小于5")
    if liebiao >5:
        print("大于5")
    else:
        print("小于5")
    if yuanzu >5:
        print("大于5")
    else:
        print("小于5")
    return (zifuchuan,liebiao,yuanzu)
 
func(‘dadadad‘,‘[1,2,3]‘,{1,2,3})
View Code

14,写函数监测用户传入的对象(字符,列表,元组)的每一个元素是否有空内容

技术分享图片
def func(n):
    for i in a:
        i = str(i)
        if ‘‘ in i:
            return (‘空格: ‘,i)
        else:
            return (‘没空格‘)
 
a = (‘dasdsd dasd‘,‘ds‘)
res = func(a)
print(res)
View Code

15,写函数,检查传入列表的长度,如果大于2,那么仅仅保留前两个长度的内容,并将新内容返回给调用者

技术分享图片
def func(li):
    len_li = len(li)
    if len_li>2:
        print("列表长度大于2")
        new_li = li[0:2]
    return (new_li)
 
res = func([12,12,45,78,32,12])
print(res)
View Code

16,写函数,检查获取传入列表或元组的所有奇数位索引对应的元素,并将其作为新列表返回给调用者

技术分享图片
def func(li,tup):
    li = []
    tup = []
    for i in range(len(li)):
        if i %2 ==1:
            li.append(li[i])
    print(li)
 
    for j in range(len(tup)):
        if j %2 ==1:
            tup.append(tup[j])
    print(tup)
 
    return  (li,tup)
res = func([1,2,3,4,5,6,7,8,9],(1,2,3,11,21,4,5,6,7))
print(res)
View Code

17,写函数,检查传入字典的每一个value的长度,如果大于2,那么仅仅保存前两个长度的内容,并将新内容返回给调用者

dic={"andyzhang":32,'yanyan':"duyanyan","niuniu":"zhixuan,zhang"}
def func(dic):
ret = {}
for k,v in dic.items():
if type(v) != str:
v = str(v)
if len(v) > 2:
ret[k]= v[:2]
else:
ret[k] = v
return ret
a = func(dic)
print(a)

 18,写函数,计算传入字符串中的【数字】、【字母】、【空格】和【其他】的个数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 18,写函数,计算传入字符串中的【数字】、【字母】、【空格】和【其他】的个数
def func(strr):
    digit_number = 0
    space_number = 0
    alpha_number = 0
    else_number = 0
    for in strr:
        if i.isdigit():
            digit_number +=1
        elif i.isspace():
            space_number +=1
        elif i.isalpha():
            alpha_number +=1
        else:
            else_number +=1
    return ("数字,空格,字母,其他内容分别有:",(digit_number,space_number,alpha_number,else_number))
res = func(‘sda!@#$%^&1234567dfghj da da ‘)
print(res)
# (‘数字,空格,字母,其他内容分别有:‘, (7, 3,
  1. logging模块有几个日志级别?

    答案
     logging模块共5个级别,它们分别是:
     DEBUG INFO WARNING ERROR CRITICAL
    
  2. 请配置logging模块,使其在屏幕和文件里同时打印以下格式的日志

    2017-10-18 15:56:26,613 - access - ERROR - account [1234] too many login attempts
  3. import logging
    logger = logging.getLogger("access")
    logger.setLevel(logging.INFO)
    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(lineno)s")
    handler = logging.FileHandler("log.txt")
    handler.setLevel(logging.INFO)
    handler.setFormatter(formatter)

    console = logging.StreamHandler()
    console.setFormatter(formatter)
    console.setLevel(logging.INFO)

    logger.addHandler(handler)
    logger.addHandler(console)

    logger.error("account [1234] too many login attempts")
  4. json、pickle、shelve三个区别是什么?

    答案
     首先,这三个模块都是序列化工具。
     1. json是所有语言的序列化工具,优点跨语言、体积小.只能序列化一些基本的数据类型。intstrlist	upledict
     pickle是python语言特有序列化工具,所有数据都能序列化。只能在python中使用,存储数据占空间大.
     shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式。
     2. 使用方式,json和pickle用法一样,shelve是f = shelve.open('shelve_test')
    
  5. json的作用是什么?

    答案:
     序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes
    
  6. subprocess执行命令方法有几种?

    答案吧:有三种方法,他们分别是
     run()方法
     call()方法
     Popen()方法
    
    • 为什么要设计好目录结构?
      答案:
      1.可读性高: 不熟悉这个项目的代码的人,一眼就能看懂目录结构,
    • 知道程序启动脚本是哪个,
    • 测试目录在哪儿,配置文件在哪儿等等。从而非常快速的了解这个项目。
    • 2.可维护性高: 定义好组织规则后,维护者就能很明确地知道,新增的哪个文件和代码应该放在什么目录之下。
    • 这个好处是,随着时间的推移,代码/配置的规模增加,项目结构不会混乱,仍然能够组织良好。
      
  7. 打印出命令行的第一个参数。例如:

    python argument.py luffy
    打印出 luffy
    
    答案:
    import sys
    print(sys.argv[1])
    
  8. 代码如下:

    '''
    Linux当前目录/usr/local/nginx/html/
    文件名:index.html
    '''
    import os
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath('index.html')))
    print(BASE_DIR)
    
  9. 打印的内容是什么?

    答案
    /usr/local/nginx
    
  10. os.path.dirname和os.path.abspath含义是什么?

    答案
    os.path.dirname:指定文件的目录
    os.path.abspath:指定文件的绝对路径
    
  11. 通过configparser模块完成以下功能

    文件名my.cnf
    
     [DEFAULT]
    
     [client]
     port = 3306
     socket = /data/mysql_3306/mysql.sock
    
     [mysqld]
     explicit_defaults_for_timestamp = true
     port = 3306
     socket = /data/mysql_3306/mysql.sock
     back_log = 80
     basedir = /usr/local/mysql
     tmpdir = /tmp
     datadir = /data/mysql_3306
     default-time-zone = '+8:00'
  • 修改时区 default-time-zone = '+8:00' 为 校准的全球时间 +00:00

    答案
    import configparser
    config = configparser.ConfigParser()
    config.read('my.cnf')
    config.set('mysqld','default-time-zone','+00:00')
    config.write(open('my.cnf', "w"))
    print(config['mysqld']['default-time-zone'] )
  • 删除 explicit_defaults_for_timestamp = true

    import configparser
    config = configparser.ConfigParser()
    config.read('my.cnf')
    config.remove_option('mysqld','explicit_defaults_for_timestamp')
    config.write(open('my.cnf', "w"))
  • 为DEFAULT增加一条 character-set-server = utf8

    答案:
    import configparser
    config = configparser.ConfigParser()
    config.read('my.cnf')
    config.set('DEFAULT','character-set-server','utf8')
    config.write(open('my.cnf', "w"))
  • 写一个6位随机验证码程序(使用random模块),要求验证码中至少包含一个数字、一个小写字母、一个大写字母.

  • import random
    import string
    a = ''.join(random.sample(string.ascii_lowercase + string.ascii_uppercase + string.digits,6))
    print(a)
  1. 利用正则表达式提取到 luffycity.com ,内容如下

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>luffycity.com</title>
    </head>
    <body>
    </body>
    </html>
    import re
    f = open('index.html','r',encoding='utf-8')
    data = f.read()
    print(re.findall('luffycity.com',data))
  2. 写一个用户登录验证程序,文件如下 1234.json

    {"expire_date": "2021-01-01", "id": 1234, "status": 0, "pay_day": 22, "password": "abc"}
  3. 文件如下 1234.json
    {"expire_date": "2021-01-01", "id": 1234, "status": 0, "pay_day": 22, "password": "abc"}
     
    用户名为json文件名,密码为 password。
    判断是否过期,与expire_date进行对比。
    登陆成功后,打印“登陆成功”,三次登陆失败,status值改为1,并且锁定账号。
    
    import json,time,datetime
    username = '1234.json'
    #首次登入将数据写入文件
    # data = {"expire_date": "2020-01-01", "id": 1234, "status": 0, "pay_day": 22, "password": "abc"}
    # with open('1234.json','r+',encoding='utf-8') as f:
    #     file = json.dump(data,f)
    with open('1234.json', 'r+', encoding='utf-8') as f2:
        file2 = json.load(f2)
    
    print('请登录用户名、密码进行验证:')
    
    count = 3
    while count > 0:
        user_name = input('name:>').strip()
        pass_word = input('password:>').strip()
        if file2['status'] == 1:
            print('该用户已锁定')
            exit()
        else:
            time_now = time.strftime('%Y-%m-%d')
            d1 = datetime.datetime.strptime(file2['expire_date'], '%Y-%m-%d')
            d2 = datetime.datetime.strptime(time_now, '%Y-%m-%d')
            if d1 > d2:
                if user_name == username:
                    if pass_word == file2['password']:
                        print('登录成功')
                        exit()
                    else:
                        count -= 1
                        print(f"您还有{count}次机会输入")
                        if count == 0:
                            file2['status'] = 1
                            with open('1234.json', 'w', encoding='utf-8') as f3:
                                json.dump(file2,f3)
                                break
    
                else:
                    print('用户名不存在:')
                    continue
    
            else:
                print('已过期')
                break
    复制代码
  4. 用户名为json文件名,密码为 password。

  5. 判断是否过期,与expire_date进行对比。
  6. 登陆成功后,打印“登陆成功”,三次登陆失败,status值改为1,并且锁定账号。

  7. 把第12题三次验证的密码进行hashlib加密处理。即:json文件保存为md5的值,然后用md5的值进行验证。

  8. import hashlib
    file2 = {"expire_date": "2021-01-01", "id": 1234, "status": 0, "pay_day": 22, "password": "abc"}
    hash_pass = file2['password']
    m5 = hashlib.md5()
    pass_data = m5.update(b"hash_pass")
    print(m5.digest(),type(m5.digest()))
    # print(m5.hexdigest())

    pass_word = input('>')
    pass_input = m5.update(b'pass_word')
    print(m5.digest())
    if pass_input == pass_data:
    print('nice')  
  9. 14、最近luffy买了个tesla,通过转账的形式,并且支付了5%的手续费,tesla价格为75万。文件为json,
    请用程序实现该转账行为
    。 需求如下: . ├── account │ ├── luffy.json │ └── tesla.json └── bin └── start.py 当执行start.py时,出现交互窗口 ------- Luffy Bank --------- 1. 账户信息 2. 转账 选择1 账户信息 显示luffy的当前账户余额。 选择2 转账 直接扣掉75万和利息费用并且tesla账户增加75万 import json,os,sys #取出当前文件的目录dir,
    #当前文件父目录os.path.dirname(dir)
    print(__file__)
    dir = os.path.abspath(__file__)
    dir2 = os.path.dirname(os.path.dirname(dir))
    # 取出json文件的绝对路径
    file_path1 = dir2 + "\" + "account" + "\" + "luffy.json"
    file_path2 = dir2 + "\" + "account" + "\" + "tesla.json"
    print("""
    ------- Luffy Bank ---------
    1. 账户信息
    2. 转账
    """)
    while True:
    
        choice = input("""
    请选择如下序号:
    1. 账户信息
    2. 转账
    q.退出
    >
    """)
        #  此题前提在luffy 下存入100万
        with open(file_path1, 'r', encoding='utf-8') as f:
            balance = json.load(f)
        if choice == '1':
                print(f'当前余额:{balance}万')
                continue
        if choice == '2':
            balance = balance - balance*0.05 - 75
            tesla_balance = 75
            print(f"购买tesla共花费{balance - balance*0.05 - 75},tesla账户增加{tesla_balance}")
            with open(file_path2,'w',encoding='utf-8') as f2:
               json.dump(tesla_balance,f2)
            with open(file_path1, 'w', encoding='utf-8') as f3:
               json.dump(balance, f3)
               continue
    
        elif choice == 'q':
            exit()
    复制代码

    14.1、提现

    复制代码
    提现:
    对上题增加一个需求:提现。 目录结构如下
    
    .
    ├── account
    │ └── luffy.json
    ├── bin
    │ └── start.py
    └── core
    └── withdraw.py
    当执行start.py时,出现交互窗口
    
      ------- Luffy Bank ---------
      1. 账户信息
      2. 提现
    选择1 账户信息 显示luffy的当前账户余额和信用额度。
    选择2 提现 提现金额应小于等于信用额度,利息为5%,提现金额为用户自定义。
    
    import json,os,sys
    
    #取出当前文件的父目录,
    print(__file__)
    dir = os.path.abspath(__file__)
    dir2 = os.path.dirname(os.path.dirname(dir))
    # 取出json文件的绝对路径
    file_path1 = dir2 + "\" + "account" + "\" + "luffy.json"
    file_path2 = dir2 + "\" + "account" + "\" + "tesla.json"
    print("""
    ------- Luffy Bank ---------
    1. 账户信息
    2. 提现
    """)
    data = {'balance': 100, 'credit': 50}
    with open(file_path1, 'w', encoding='utf-8') as f:
        json.dump(data,f)
    while True:
    
        choice = input("""
    请选择如下序号:
    1. 账户信息
    2. 提现
    q.退出
    >
    """)
        #  此题前提在luffy 下存入data字典信息
        #data = {'balance': 100, 'credit': 50}
        with open(file_path1, 'r', encoding='utf-8') as f:
            #json.dump(data,f)
            balance = json.load(f)
        if choice == '1':
    
            print(f"当前余额:{balance['balance']}万,信用额度:{balance['credit']}万")
            continue
        if choice == '2':
            withdraw_money = int(input('请输入提现金额:').strip())
            if withdraw_money > balance['credit']:
                print(f"提现金额超过信用额度:{balance['credit']}万,请重新输入")
            else:
                balance['balance'] = balance['balance'] - withdraw_money - withdraw_money*0.05
                print(f"剩下余额{ balance['balance']}")
            with open(file_path1, 'w', encoding='utf-8') as f2:
               json.dump(balance, f2)
               continue
    
        elif choice == 'q':
            exit()
    复制代码

    14.2、加装饰器

    复制代码
    加登装饰器
    
    import json,os,sys
    
    #取出当前文件的父目录,
    print(__file__)
    dir = os.path.abspath(__file__)
    dir2 = os.path.dirname(os.path.dirname(dir))
    # 取出json文件的绝对路径
    file_path1 = dir2 + "\" + "account" + "\" + "luffy.json"
    file_path2 = dir2 + "\" + "account" + "\" + "tesla.json"
    global withdraw,transfer
    print("""
    ------- Luffy Bank ---------
    1. 账户信息
    2. 提现
    """)
    # data = {'balance': 100, 'credit': 50}
    # with open(file_path1, 'w', encoding='utf-8') as f:
    #     json.dump(data,f)
    user_status = False
    def login(fun):
        def inner(*args,**kwargs):
            user_name = 'xiao'
            pass_word = '123'
            global user_status
            if user_status == False:
                username = input('user:>').strip()
                password = input('password:>').strip()
                if username == user_name and pass_word == password:
                    print('welcome login...')
                    user_status = True
                else:
                    print('wrong username or passerword')
            if user_status == True:
                return fun(*args,**kwargs)
        return inner
    
    @login
    def transfer():
        tesla_balance = 75
        balance['balance'] = balance['balance'] - tesla_balance * 0.05 - 75
    
        print(f"购买tesla共花费{tesla_balance * 0.05 + 75},tesla账户增加{tesla_balance}")
        with open(file_path2, 'w', encoding='utf-8') as f2:
            json.dump(tesla_balance, f2)
        with open(file_path1, 'w', encoding='utf-8') as f3:
            json.dump(balance, f3)
    @login
    def withdraw():
        withdraw_money = int(input('请输入提现金额:').strip())
        if withdraw_money > balance['credit']:
            print(f"提现金额超过信用额度:{balance['credit']}万,请重新输入")
        else:
            balance['balance'] = balance['balance'] - withdraw_money - withdraw_money*0.05
            print(f"剩下余额{ balance['balance']}")
        with open(file_path1, 'w', encoding='utf-8') as f2:
           json.dump(balance, f2)
    
    ---------------------------------主函数-----------------------------------------
    while True:
    
        choice = input("""
    请选择如下序号:
    1. 账户信息
    2. 提现
    3.转账
    q.退出
    >
    """)
        #  此题前提在luffy 下存入data字典信息
        # data = {'balance': 100, 'credit': 50}
        with open(file_path1, 'r', encoding='utf-8') as f:
            # json.dump(data,f)
            balance = json.load(f)
        if choice == '1':
            print(f"当前余额:{balance['balance']}万,信用额度:{balance['credit']}万")
            continue
    
        if choice == '2':
            withdraw()
            continue
    
        if choice == '3':
            transfer()
            continue
        elif choice == 'q':
            exit()
    复制代码

     14.3、加日志功能

    复制代码
    加日志功能
    
    对第15题的用户转账、登录、提现操作均通过logging模块记录日志,日志文件位置如下
    
    .
    ├── account
    │ └── luffy.json
    ├── bin
    │ └── start.py
    └── core
    | └── withdraw.py
    └── logs
    └── bank.log
    
    import json,os,sys
    
    #取出当前文件的父目录,
    print(__file__)
    dir = os.path.abspath(__file__)
    dir2 = os.path.dirname(os.path.dirname(dir))
    # 取出json文件的绝对路径
    file_path1 = dir2 + "\" + "account" + "\" + "luffy.json"
    file_path2 = dir2 + "\" + "account" + "\" + "tesla.json"
    #bank.logs绝对路径
    file_path3 = os.path.dirname(dir)+"\" + "bank.log"
    
    global withdraw,transfer
    
    #日志
    # 将日志同时输出到屏幕和日志文件
    import logging
    #logger提供了应用程序可以直接使用的接口;
    logger = logging.getLogger('wed')
    logger.setLevel(level = logging.INFO)
    #handler将(logger创建的)日志记录发送到合适的目的输出;
    # FileHandler()输出至屏幕
    handler = logging.FileHandler(file_path3)
    handler.setLevel(logging.INFO)
    #formatter决定日志记录的最终输出格式。
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)
    # StreamHandler()输出至屏幕
    console = logging.StreamHandler()
    console.setLevel(logging.INFO)
    #增加指定的Handler
    logger.addHandler(handler)
    logger.addHandler(console)
    
    
    print("""
    ------- Luffy Bank ---------
    1. 账户信息
    2. 提现
    """)
    # data = {'balance': 100, 'credit': 50}
    # with open(file_path1, 'w', encoding='utf-8') as f:
    #     json.dump(data,f)
    user_status = False
    def login(fun):
        def inner(*args,**kwargs):
            user_name = 'xiao'
            pass_word = '123'
            global user_status
            if user_status == False:
                username = input('user:>').strip()
                password = input('password:>').strip()
                if username == user_name and pass_word == password:
                    logger.info('----登录-----')
                    print('welcome login...')
                    user_status = True
                else:
                    print('wrong username or passerword')
            if user_status == True:
                return fun(*args,**kwargs)
        return inner
    
    @login
    def transfer():
        tesla_balance = 75
        balance['balance'] = balance['balance'] - tesla_balance * 0.05 - 75
    
        print(f"购买tesla共花费{tesla_balance * 0.05 + 75},tesla账户增加{tesla_balance}")
        with open(file_path2, 'w', encoding='utf-8') as f2:
            json.dump(tesla_balance, f2)
        with open(file_path1, 'w', encoding='utf-8') as f3:
            json.dump(balance, f3)
    @login
    def withdraw():
        withdraw_money = int(input('请输入提现金额:').strip())
        if withdraw_money > balance['credit']:
            print(f"提现金额超过信用额度:{balance['credit']}万,请重新输入")
        else:
            balance['balance'] = balance['balance'] - withdraw_money - withdraw_money*0.05
            print(f"剩下余额{ balance['balance']}")
        with open(file_path1, 'w', encoding='utf-8') as f2:
           json.dump(balance, f2)
    
    
    while True:
    
        choice = input("""
    请选择如下序号:
    1. 账户信息
    2. 提现
    3.转账
    q.退出
    >
    """)
        #  此题前提在luffy 下存入data字典信息
        # data = {'balance': 100, 'credit': 50}
        with open(file_path1, 'r', encoding='utf-8') as f:
            # json.dump(data,f)
            balance = json.load(f)
        if choice == '1':
            logger.info('----显示账户信息-----')
            print(f"当前余额:{balance['balance']}万,信用额度:{balance['credit']}万")
            continue
    
        if choice == '2':
            logger.info('----提现-----')
            print()
            withdraw()
            continue
    
        if choice == '3':
            logger.info('----转账-----')
            transfer()
            continue
        elif choice == 'q':
            exit()

    利用subprocess打印出当前的目录

    #第一种方法

    import subprocess

    res = subprocess.Popen('dir()',shell=True,stdout=subprocess.PIPE)
    res1=res.communicate()
    print(res1[0].decode('gbk'))

    #第二种方法

    a = os.popen('dir').read()
    print(a)

    1. 利用内置函数 filter 和自定义函数获取l1大于33的所有元素 l1 = [11, 22, 33, 44, 55]
    print(list(filter(lambda x:x>33,l1)))

    2. 写日志11/26/2017 10:44:21 PM bug 24 ,将内容写入文件example.log中 (编程)
    内置格式要求有 时间 内容 行号
    import logging
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.INFO)

    formatter = logging.Formatter('%(asctime)s -%(name)s - %(levelname)s - %(message)s - %(lineno)d')

    handler = logging.FileHandler('example.log',encoding='utf-8')
    handler.setFormatter(formatter)
    handler.setLevel(logging.INFO)

    logger.addHandler(handler)

    logger.info("这是一个新信息")
    logger.error("这是错误信息")
     

    Python-闭包详解

    在函数编程中经常用到闭包。闭包是什么,它是怎么产生的及用来解决什么问题呢。给出字面的定义先:闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)(想想Erlang的外层函数传入一个参数a, 内层函数依旧传入一个参数b, 内层函数使用a和b, 最后返回内层函数)。这个从字面上很难理解,特别对于一直使用命令式语言进行编程的程序员们。本文将结合实例代码进行解释。
    函数是什么
    地球人都知道:函数只是一段可执行代码,编译后就“固化”了,每个函数在内存中只有一份实例,得到函数的入口点便可以执行函数了。在函数式编程语言中,函 数是一等公民(First class value:第一类对象,我们不需要像命令式语言中那样借助函数指针,委托操作函数),函数可以作为另一个函数的参数或返回值,可以赋给一个变量。函数可 以嵌套定义,即在一个函数内部可以定义另一个函数,有了嵌套函数这种结构,便会产生闭包问题。如:

    复制代码
    >>> def ExFunc(n):
         sum=n
         def InsFunc():
                 return sum+1
         return InsFunc

    >>> myFunc=ExFunc(10)
    >>> myFunc()
    11
    >>> myAnotherFunc=ExFunc(20)
    >>> myAnotherFunc()
    21
    >>> myFunc()
    11
    >>> myAnotherFunc()
    21
    >>>
    #写一个装饰器,函数执行之前打印before,执行之后,打印被装饰的函数的执行时间 和 finish。
    import time

    def exfunc(func):
    def inner(*args,**kwargs):
    print('before')
    start_time = time.time()
    res = func()
    stop_time = time.time()
    print("执行程序用时%s"%(stop_time - start_time))
    print('finish')
    return res
    return inner

    @exfunc
    def sayhi():
    time.sleep(1)
    print('hello')

    sayhi()

    #写一个装饰器,函数执行之前打印before,执行之后,打印被装饰的函数的执行时间 和 finish。
    import subprocess
    ret = subprocess.Popen("dir",shell=True,stdout=subprocess.PIPE)
    ret = ret.communicate()
    print(ret[0].decode("gbk"))

    #利用hashlib模块和open函数写一个三次验证代码,要求如下:(编程)
    #1. 密码是加密的。
    #2. 三次登陆失败锁定账号在文件当中。

    import hashlib,json
    username = '1234.json'
    with open('1234.json','r',encoding='utf-8')as f:
    file = json.load(f)
    # print(file['password'])
    hash_pass = hashlib.md5(file['password'].encode('utf-8'))

    count = 3
    while count >0:
    user_name= input("请输入用户名:").strip()
    password = input("请输入密码:").strip()
    if user_name == username:
    hash_password = hashlib.md5(password.encode('utf-8'))
    if hash_pass.digest() == hash_password.digest():
    print("登录成功")
    else:
    count -=1
    print('密码错误,还剩%s次机会'%count)
    if count == 0:
    file['status'] = 1
    print(file)
    with open('1234.json','w',encoding='utf-8')as f1:
    json.dump(file,f1)
    else:
    print('用户名不存在')
    exit()





原文地址:https://www.cnblogs.com/anzhangjun/p/8650290.html