前言:

继续前进

基础回顾:

1、集合

集合有2个重要作用:关系测试(并集,差集,交集)和去重。

2、文件编码

2.7上默认文件编码是ASCII码,因为不支持中文,就出了GB2312,在2.7上要支持中文就必须申明文件编码以UTF-8的格式,UTF-8与GB2312的关系?

UTF-8是Unicode的扩展集合,Unicode包括全国地区的编码,中国很多开始程序还是以GBK的格式,GBK向下兼容GB2312,Windows默认编码是GBK。

Unicode为何要做出来?为了节省空间,存英文中文都是2个字节,本来我用ASCII码存英文只用1个字节,但是现在用你2个,所以出了UTF-8 ,存英文是1个字节,中文统一3个字节。

假如1个文件是GBK编码的,另外一个是UTF-8,如果它要读这个文件,就要进行一个转换,但是他们之间不能直接转换,这个时候就涉及到了转码的问题。所以GBK转换成UTF-8,语法是先decode 成Unicode,然后在encode成utf-8,见下图:

一个初学者的辛酸路程-装饰器-5

在3.0中,默认编码是Unicode,在2.7中要打印中文就得申明字符编码 # -*- coding:utf-8 -*- 

在3.0可以不写,默认文件编码就是Unicode,那么现在文件编码就是Unicode,因为Unicode本来也支持中文,按2个字节存放,不需要转换成utf-8,要想变成utf-8也得encode一下,如下所示:

a= '我是'.encode("utf-8")

。当然也可以申明字符编码 # -*- coding:utf-8 -*- ,那么现在的文件编码就是utf-8了。

3、函数

 格式如下:

def  func_name():
        pass

位置参数,比如 arg1 和 arg2

def  func_name(arg1,arg2):
      pass

func_name(5,3)

5对应的是arg1  3对应的是arg2

关键参数,可以指定参数名,比如:

def  func_name(arg1,arg2,arg3):
        pass

func_name(1,2,arg3=5)

注意,关键参数不能写在位置参数前面。

多个参数,就用到了*args,比如:

def   func_name(arg1,arg2,*args):
        pass

func_name(4,5,6,7,8)
那么打印出来效果
4,5,(6,7,8)

把后面非固定参数写成了元祖

**kwargs ,打印出来是一个字典,例如

def func_name(arg1,arg2,arg3,*args,**kwargs):
        pass

func_name(3,4,55,666,77,name=xiedi)

打印出来的结果
3,4,55,(666,77),{'name':'xiedi'}

4、局部变量和全局变量

总的来说,局部变量只对函数内生效,对函数外不起作用。

它涉及到一个作用域的问题,只是在函数里生效的,函数执行完毕,变量就没了,作用域只允许在函数里改东西。

找变量的顺序,先从内到外找变量。

如果非得改变它的作用域,就加一个global,但是不建议这么做,例如

age = 22
def change_age():
        global age
        age = 24

5、返回值

返回值是因为我想得到函数的执行结果,它还代表着程序的结束

6、递归

递归相当于自己调自己,有几个条件:

1、要有一个明确的结束条件。

因为递归相当于一层进入一层。

2、问题规模每递归一次都应该比上一次的问题规模有所减少。

3、效率低

7、高阶函数

把一个函数当做另一个函数的参数传进去,返回的时候要用到这个函数。

函数式编程是不需要变量的,纯粹是一个映射关系,函数式编程是没有副作用的,就是传进去的数据是确定的,得出来的结果也是固定的。

8、文件操作

打开模式:

f = open 

r,w,a 

r是读,w是写,它会覆盖,a是追加,r+是读写模式,写到后面,追加的模式。

w+ 是写读,以写的模式打开文件,如果文件存在,直接覆盖。

a+追加写读

rb二进制模式打开,全部是字节格式

获得文件句柄

操作:

 f.

关闭:

f.close

 

接下来就是重点了,先来个装饰器。顾名思义,装饰一下。

一、装饰器

从字面意思来看,器代表函数的意思,可以说,装饰器本身就是函数,都是用def语法来定义的。

装饰器:

定义:本质是函数,(装饰其他函数)

为其他函数添加附加功能。

①先来看个简单的,在没学函数之前,我想给定义的函数打个日志,写法如下:

def  test1():
    pass
    print('logging')

def test2():
    pass
    print('logging')
#调用
test1()
test2()

②接下来学了函数,我就把打日志定义成一个函数

# -*- coding: utf-8 -*-
#Author: Leon xie

def logger():
    print('logging')

def  test1():
    pass
    logger()

def test2():
    pass
    logger()
#调用
test1()
test2()

假设我写的函数已经上线运行了,某一天,我有个需求,在这个里面新增一个功能,那怎么去做这个事?

最简单的就是:挨个找到100个函数,加上去。但是问题是程序已经运行了,我刚才操作是修改我程序的源代码,会有风险发生。

所以说,我要新增一个功能,不能够修改函数的源代码,函数一旦写好了,原则上不能动源代码了。

所以就有了下面的原则:

原则:

1、不能修改被装饰函数的源代码。

2、不能修改被装饰的函数的调用方式。

装饰器对于被装饰函数是完全透明的。他没有动我的源代码,我该怎么调用运行就怎么运行。

 

举例子:

定义1个函数

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: Leon xie

import time

def test1():
    time.sleep(3)
    print('in the test1')

test1()
这个函数实现的就是 睡3秒然后打印

接下来写个装饰器:

用的时候只要在函数前面加一个“@函数名”, 即可

先睡3s然后打印,随后统计了一个test1函数的运行时间。

第一:装饰器本质就是一个函数

第二:装饰器不修改被装饰函数的源代码和调用方式

第三:对于函数 test1来说,装饰器完全不存在。

实现这个装饰器的功能需要哪些知识呢?

1、函数即变量

2、高阶函数

3、嵌套函数

最终:

高阶函数+嵌套函数===>装饰器

 

我们来复习一下变量:

变量是存在内存当中,比如我x=1,那么它是如何存在变量中呢?如下图:

其实我要说的就是函数即变量。

变量调用加上变量名直接调用。

函数调用呢就是函数加个小括号。    test()

一个初学者的辛酸路程-装饰器-5

 python解释器中有一个概念叫做引用计数。

比如x=1 ,y=x,那么就是2次计数。

x和y相当于房间的门牌号,如果没有门牌号了,那么内存里的1就会被清空。

匿名函数:

有的函数是不定义名字的。

例如:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: Leon xie
#为了后面调用,我起了一个变量名,这个函数没有名字
calc = lambda x:x*3
print(calc(3))
输出结果
9

匿名函数没有def起函数名。

小结:

函数就是一个变量,定义一个函数,就是把函数体付给了这个函数名。

变量特性是:内存回收。

 

既然说函数即变量那么下面这个函数如何存放呢?

def foo():

   print('in the foo')

       bar()

foo()

这个函数就回报错,如下图所示:

一个初学者的辛酸路程-装饰器-5

变量是先定义,后引用,函数也是一样。

看下面这个例子:可以正常调用,只要在调用之前存在就可以调用

def foo():

   print('in the foo')

       bar()

def bar():

  print('in the bar')

foo()

 一个初学者的辛酸路程-装饰器-5

 

 高阶函数:(满足下面2个条件)

a:把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)

b:返回值中包含函数名

按照第一条原则写一个

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: Leon xie

def bar():
    print('in the bar')

def test1(func):
    print(func)

test1(bar)

输出结果

<function bar at 0x0000000000A69268>
一段内存地址

上面相当于

func= bar 是一个门牌地址

func()是可以运行的,所以可以写成这样 类似于x=1   y=x

一个初学者的辛酸路程-装饰器-5

那么就有了下面的函数,附加一个计数的功能。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: Leon xie

import  time
def bar():
    time.sleep(3)
    print('in the bar')

def test1(func):
    start_time =time.time()
    #运行一下func
    func()
    stop_time =time.time()
    #传进来的运行时间不是test1
    print("the func run time is %s" %(stop_time-start_time))

test1(bar)


输出结果

in the bar
the func run time is 3.0002999305725098

这里在没有修改源代码的基础上新增了一个计数的功能。不过我们知道装饰器还有一个条件就是不改变调用方式。所以我们接着往下看

一个初学者的辛酸路程-装饰器-5

嵌套函数举例:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: Leon xie

def foo():
    print('in the foo')
    def bar():
        print('in the bar')

    bar()
foo()
输出结果

in the foo
in the bar

 

最后装饰器效果:

#写个装饰器统计运行的时间

import time

def timer(func):  #timer(test1)  test1 的内存地址给了func
    def deco(*args,**kwargs):
        start_time=time.time()
        func(*args,**kwargs)
        stop_time= time.time()
        print('the func run time is %s' %(stop_time-start_time))
    return deco     #返回了deco的内存地址

#嵌套函数写成下面的形式
#def timer():
 #   def deco():
   #     pass

@timer   #test1= timer(test1)
def  test1():
    time.sleep(1)
    print('in the test1')

@timer   #test2= timer(test2)
def test2(name,age):
    time.sleep(1)
    print("test2:",name,age)

test1()
test2("xiedi",22)

输出结果

in the test1
the func run time is 1.0
test2: xiedi 22
the func run time is 1.0

升级

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: Leon xie

#需求:公司有网站,有很多页面,模拟1个页面1个函数,在之前情况谁都可以登录没有任何验证
#100个页面有20个登录以后才能看到,就说给20个加入验证功能。

import time
user,passwd = 'xiedi','123'
def auth(func):
    def wrapper(*args,**kwargs):
        username = input("Username:").strip()
        password = input("Password:").strip()

        if user == username and passwd == password:
            print("\033[32;1mUser has passed authentication\033[0m")
            res = func(*args,**kwargs)
            print("--afterauthenticaion")
            return res
        else:
            exit("\033[31;1mInvalid username or password\033[0m")
    return wrapper

def index():
    print("welcome to index page")

@auth
def home():
    print("welcome to hoem page")
    return "from home"

@auth
def bbs():
    print("welcome to bbs page")

index()
print(home())
bbs()
View Code

相关文章:

  • 2021-10-16
  • 2021-05-21
  • 2021-05-29
  • 2021-10-19
  • 2021-09-02
  • 2021-08-19
  • 2021-04-10
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-21
  • 2022-12-23
  • 2021-04-08
相关资源
相似解决方案