python函数的高级应用

课程目标

  1. 理解Python中函数即变量
  2. Map函数
  3. Reduce函数
  4. 匿名函数
  5. 装饰器(设计模式)基于以上理论

理解Python中函数即变量

• 变量可以指向函数
• 函数名也是变量
• 传入函数
• 函数本身也可以赋值给变量,即:变量可以指向函数

Python内置的map函数
• map()函数接收两个参数,一个是函数,一个是Iterable
• map将传入的函数依次作用到序列的每个元素,并把结果作为
新的Iterator返回
• >>> def f(x):
… return x * x

>>> r = map(f, [1, 2, 3, 4, 5, 6, 7]) >>> list(r)
[1, 4, 9, 16, 25, 36, 49]

Python内置的reduce函数
• reduce把一个函数作用在一个序列[x1, x2, x3, …]上 ,reduce
把结果继续和序列的下一个元素做累积计算
• reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4) • 把序列[7,8,3,4,9,7]变换成整数783497

>>> from functools import reduce
>>> def fn(x, y):
... return x * 10 + y
>>> reduce(fn, [])

装饰器模式原理
• 在代码运行期间动态增加功能的方式,称为“装饰器”
(Decorator) • @property
• @setter

# abs(-10)函数调用,abs是函数本身
print(abs(-10))

# abs = 10
#
# abs函数被覆盖掉

# 把函数当作参数传递给其他函数
# 代理模式在平常开发时非常常用
def add(x,y,f):
    return f(x)+f(y)

print(add(-5,-6,abs))

'''
    map函数
'''

l = [1,2,3,4,5,6,7,8,9,]

def f(x):
    return x*x

m = map(f,l)
print(m)
print(list(m))

# l 列表中每个int转换成字符串
l = [1,2,3,4,5,6,7,8,9,]

print(list(map(str,l)))

# 把一个list组成一个整数
l= [4,2,5,7,8,9]
from functools import reduce
def f(x,y):
    return x*10 + y

print(reduce(f,l))
print(type(reduce(f,l)))

#str() int() 内部实现的原理
# '5632'==》5632
# 1.把字符串每个元素取出来,转化成对应的数字,得到一个数字序列
# 2.两个数字序列每两个乘以10 相加,得到一个整数

def f(x,y):
    return x*10 + y

def char2num(s):
    digits = {
    
    '0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
    return digits[s]

s1 = '5632'

nums = reduce(f,map(char2num,s1))
print(nums)


'''
    匿名函数 在函数中去定义函数,只被当前定义的函数所调用
'''

DIGITS = {
    
    '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}

def str2int(s):
    def f(x, y):
        return x * 10 + y
    def char2num(s):
        return DIGITS[s]
    return reduce(f,map(char2num,s))

print(str2int('6463745'))

# lambda 表达式

def str2int(s):
    def char2num(s):
        return DIGITS[s]
    return reduce(lambda x,y:x*10+y,map(char2num,s))
print(str2int('234'))

'''
    装饰器的使用
'''

# 面试的时候都问装饰器(热点问题)
import datetime
# 定义一个装饰器来升级now函数 以一个函数作为参数,并返回一个函数
def log(f):
    #匿名函数
    def writediary(*args,**kw): #对参数没有限制
        # 把返回值返回给s,不用写close
        with open('./a.txt','w') as f1:
            f1.write(f.__name__)
            print('写入日志成功,函数名字是;%s'%f.__name__)
            return f(*args,**kw)
    return writediary

#装饰器调用 @
@log
def now():
    print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))

#调用方式1
# ff = log(now)
#

# ff()
# 调用方式2
now()


'''
    Python内置的装饰器 @property @setter
'''

class Student(object):
    def __init__(self,score):
        self.__score = score

    def get_score(self):
         return self.__score

    def set_score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self.__score = value

stu1 = Student(90)

print(stu1.set_score(85))
print(stu1.get_score())


# 加上装饰器,方法变属性
class Student(object):
    def __init__(self,score):
        self.__score = score

    @property
    def score(self):
         return self.__score

    @score.setter
    def score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self.__score = value


stu2 = Student('67')

stu2.score = 59
print(stu2.score)

# 作业
# #
# # • 利用map()函数,把用户输入的不规范的英文单词,变为首字母大
# # 写,其他小写的规范名字。输入:
# # [‘MIKE’, ‘Adidas’, ’coffee‘],输出:
# # [’Mike‘, ’Adidas‘, ’Coffee‘]:
#

#方式一
# def normalize(name):
#     result = name[0].upper() + name[1:].lower()
#     return result
#
#
# L1 = ['MIKE', 'Adidas', 'coffee']
# L2 = list(map(normalize, L1))
#
# print(L2)

#方式二
# L = ['adam','LISA','TOM']
# def normalize(name):
#     return list(map(lambda x:x.capitalize(),name))

# print(normalize(L))


# • 请设计一个装饰器,它可以作用于任何函数上,打印函数执行时间:
# def metric(fn):
# print('%s executed in %s ms' % (fn.__name__, 10.24))
# return fn

import time
def metric(fn):
    # 匿名函数
    def execute_time(*args,**kwargs):
        #起始时间
        start_time = time.time()
        #外部传入的参数(函数传参)
        l=fn(*args,**kwargs)
        #结束时间
        end_time = time.time()
        print('耗时:{:.4f}s'.format(end_time - start_time))
        return l
    #返回函数的值
    return execute_time
# 装饰器用法,相当于metric(exexute_fn)
@metric
# 定义一个普通的遍历函数
def execute_fn(int):
    boss = 0
    for i in range(int):
        boss += i
        i += 1
    return boss
# 在装饰器的作用下,相当于调用了metric函数中的execute_time函数,metric(execute_fn)
execute_fn(12000)


猜你喜欢

转载自blog.csdn.net/weixin_42873348/article/details/107621738