【python 高级编程】lambda(搭配函数), 生成器,迭代器,装饰器,静态、类方法,参数等

参数

*args表示填入多个参数,函数体内args代表的是输入参数组成的元祖
**kwargs表示填入多个参数对,函数体kwargs代表的是输入参数对组成的字典

def A(a,*args):
    print(args)

A(1,2,3,4)

def B(**args):
    print(args)

B(x=1,b=2)


def C(a,*par1,**par2):
    print(a,par1,par2)

C(1,2,3,4,x=1,y=2,d=3)

(2, 3, 4)
{'x': 1, 'b': 2}
1 (2, 3, 4) {'x': 1, 'y': 2, 'd': 3}

lambda用法:

1 作为函数:

def sum(a,b):
    return a+b
sum = lambda x,y:x+y
sum(a,b)#same result

面试题:
使用lambda将[‘1’,‘2’,‘3’]转化为int

transfer = lambda arr: [int(i) for i in arr]
transfer(arr)

2 初始化时赋值其他函数
屏蔽time的sleep功能。

time.sleep = lambda x:None
time.sleep(3)#nothing will happen

3 lambda作为其他函数的参数
排序中

res = filter(lambda x: x%2 == 0,[1,2,3,4,5])#py3.0 return object
print(list(res))

res = map(lambda x,y:x+y,[1,2,3,4],[2,3,4])
print(list(res))

dic = {3:'b',1:'c',2:'a'}
res = sorted(dic.items(),key = lambda x:x[1])#print all in the order of values
print(res)

res = sorted(dic.items(),key = lambda x:x[0])
print(res)

res = sorted(dic.keys(),key = lambda x:x)#print keys in their order
print(res)

res = sorted(dic.values(),key = lambda x:x)
print(res)

res=reduce(lambda x,y,:'{},{}'.format(x,y),[1,2,3,4,5,6,7])#connect x and y with ,. the operation will be excuted after first two then iterate on three.
print(res)

生成器,迭代器,装饰器

迭代器,用以生成可以迭代的对象。然后再调用next方法进行迭代

a = [2,4,1,4,5,6]
new_a = iter(a)#let a be object of iteration then use next to print
print(new_a)
print(next(new_a))
print(new_a)
print(next(new_a))
print(new_a)
print(next(new_a))

print(range(6))
for i in a:
    print(i)


a = [2,4,1,4,5,6]
new_a = iter(a)#let a be object of iteration then use next to print
while True:
    try:
        print(next(new_a))
    except StopIteration:
        print('end')
        break

如果长度不够时调用next方法将抛出 StopIteration 的error。

重构iter与next方法。事实上所有类都是 继承 Object类,然后重构内部的方法。
重构:

class Myitr:
    def __iter__(self):#iter return self
        self.val = 1
        return self
    def __next__(self):# next return its new value for one iteration
        if self.val <=10:
            self.val+=1
            return self.val
        else:
            raise StopIteration
my = Myitr()
new = iter(my)
'''print(new.val)###
print(next(new))
print(next(new))
print(next(new))'''

print('########')
#for i in range(100):
#    print(next(new))
for i in new:
    print(i)#first start from 2 because next return +1 first!!

itration对象有点类似 range()产生的对象,可以通过循环进行调用。

再看生成器,其实就是利用yield建立一个可以暂停的 迭代器对象。在循环中保存当时的信息。(只要使用了yield,就会有这种效果,内部变量在迭代时进行暂停的操作)

def fabonacci(x):
    count = 0
    a = 0
    b = 1
    while count<x:
        yield b
        b,a = a+b,b
        count+=1

test = fabonacci(10)
print(test)
for i in test:
    print(i)
print('########')
import sys
while True:
    try:
        print(next(test))#if there is no val in the next, StopIteration error will raise
    except:
        sys.exit()

test本质就是一个迭代器对象,使用next或者for循环可以进行迭代。

装饰器,装饰器通常是一个命名的对象(不允许使用lambda表达式),在被(装饰函数)调用时接受单一参数,并返回另一个可调用对象。任何含有__ call __ 的对象都可以用作装饰器

@A
def B

A(B)

这两个是相等的

@a
@b
@c
def f ():
    pass

f = a(b(c(f)))

作为一个方法的装饰器

def A(cls):
	def B(*args,**kwargs):
		result = func(*args,**kwargs)
		return result
	return B
@A
class C:
	pass

这里注意的是,方法A下的return B不能直接初始化,需要在call的时候初始化并传递参数

作为一个类的装饰器:

class A:
	def __init__(self,func):
		self.func = func
	def __call__(self,*args,**kwargs):
		res = self.func(*args,**kwargs)
		return res

参数化装饰器:

def A(num):
	def B(func):
		def C(**args,**kwargs):
			res = None
			for _ in range(num):
				res = func(*args,**kwargs)
			return res
		return C
	return B

调用时传递循环参数,可以得到连续的func输出。第一层传递迭代次数,第二层传递func,第三层传递参数

保存内省的装饰器:
使用装饰器的常见错误是在使用装饰器时不保存函数元数据(主要是文档字符串和原始函数名)。前面所有示例都存在这个问题。装饰器组合创建了一个新函数,并返回一个新对象,但却完全没有考虑原始函数的标识
解决方案:
在第二层添加 wraps(dunc)

注意:
使用自定义装饰器时,会导致 原函数 A.__ name __返回装饰器的方法名。在装饰器函数中使用 @wraps(func)可以保留函数名

常用领域:插入日志,性能测试,事务处理,缓存,权限校验等
本质是传递初始化函数或方法到 装饰器 (甚至可以携带参数)

引申:普通方法,静态方法,类方法

在这里插入代码片class A:
    expl = 'this is test1'

    def __init__(self):
        pass


    def normal_method(self):
        print(self.expl)


    @classmethod
    def cls_method(cls):
        print(cls.expl)

    @staticmethod
    def static_method():
        x=1
        print('nothing is happening,and x={}'.format(x))

A.static_method()
A.cls_method()
a = A()
a.expl = 'this is new test2'
a.normal_method()
a.cls_method()    #not change
a.static_method()  #no matter whther it is initialization, it will run normally


nothing is happening,and x=1
this is test1
this is new test2
this is test1
nothing is happening,and x=1

普通方法必须初始化以后才可以调用。
静态方法可以不用初始化就调用,输出自带的属性值。
类方法同样可以不用初始化调用,它会返回类属性的本身值,不会随着初始化以后的内容变化。

引申:单例模式

class B(object):
    x='test'

def singleton(cls):
    _instance = {}
    def check(*args,**kwargs):
        if cls not in _instance:
            print('init 1')
            _instance[cls] = cls(*args,**kwargs)

        return _instance[cls]

    return check


@singleton
class A():
    x='test'


a1 = A()
a2 = A()
b1 = B()
b2 = B()
print(a1,a2)
print(b1,b2)


init 1
<__main__.A object at 0x000001A3CAB79E48> <__main__.A object at 0x000001A3CAB79E48>
<__main__.B object at 0x000001A3CAB8E208> <__main__.B object at 0x000001A3CAB8E240>

可以看到单例模式下,两次初始化的内存位置是一样的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值