函数被调用时:
1、函数后有(),是v——函数执行,要调回头或跳到下方某处,进入此函数块内执行;
2、只有函数名而无(),是n——函数体,按照正常顺序往下执行,不用跳来跳去。
理解装饰器,可把头&尾的def finalFunc(*args, **kwargs):、return finalFunc,视为不存在。
*******************分割线*******************
函数内若改了全局变量v,并使之同步到函数外,则要在此函数内的首行加句global v。
函数的形参若设了list、set、dict等可变类型的默认值,则似全局变量 :
import random
def foo(a={2}):
a.add(random.randint(1,50))
print(a)
for x in range(9):
foo()
*******************分割线*******************
f用于{}的格式化,{}内是变量或函数的某个形参;%s等%家族的格式化则不适用。
f'{xxx}'内的+-/*等Python内置对象,意义没变,只想表示普通str则写在{}外,如{}和{}之间。
def func(name):
greet='good morning'
print(f'{greet},{name}')
func('小明')
****************************************分割线****************************************
高阶函数:参数为函数;闭包:返回值为函数;装饰器:返回值为函数的高阶函数
高阶函数:
from functools import reduce
# map的首参函数逐一作用于二参序列的各元素,返回同len的序列;
# 而reduce的首参函数必须有俩参,迭代处理二参序列的相邻元素,返回1个值
def accumulate(start, end, handle, sign):
t = map(handle, range(start, end + 1))
return reduce(lambda x, y: eval(f'{x}{sign}{y}'), t)
def add(start, end, handle):
return accumulate(start, end, handle, '+')
def product(start, end, handle):
return accumulate(start, end, handle, '*')
def handle(n):
return n ** 2
print(add(1,4, handle))
****************************************分割线****************************************
闭包:
def count():
#x=i:x是匿名函数的形参,i是实参;不写=i,则报错lambda()缺少参数(实参)
return [lambda x=i:x*x for i in range(1,4)] #生成3个传来了实参的函数体
x,y,z=count()
print(x(),y(),z(),sep=';')
*******************分割线*******************
def func():
x,y=1,2
return lambda m=x,n=y:m+n #m=x,n=y:x和y是默认实参
print(func()()) #输出3,即1+2
print(func()(3,7)) #输出10,即3+7
****************************************分割线****************************************
#函数实现的双层装饰器
from functools import wraps #保持被装饰函数原有的属性值和方法行为
def outer(initialFunc): # 给原函数套俩彩盒,由外至内逐层开盒
@wraps(initialFunc) #用wraps保护传来的被装饰函数的属性和方法
def finalFunc(*args, **kwargs):
print('begin to run outer decorator')
initialResponse=initialFunc(*args, **kwargs) #等同inner('自带参数')(func)(x,y=6)
print('end outer decorator')
return initialResponse
return finalFunc
def inner(selfArgument): # 高阶装饰器:自身也带参数
def realDecorator(initialFunc): #高阶装饰器,要多一层方法嵌套
@wraps(initialFunc)
def finalFunc(*args, **kwargs): # 装饰器的俩轮子
print(selfArgument, '——begion to run higher decorator')
#参数*和**是装饰器的俩轮子,()是装饰器的一对翅膀
initialResponse=initialFunc(*args, **kwargs) + 9 #暂不return,让后面的print也能执行
print('end higher decorator')
return initialResponse #下面两行的return不能加(),是普通函数体,不是翅膀
return finalFunc
return realDecorator
@outer # func(x,y=6)=outer(inner('自带参数')(func))(x,y=6)
@inner('自带参数') # func(x,y=6)=inner('自带参数')(func)(x,y=6)
def initialFunc(x, y=6):
print('begin to run initial function')
return x + y # 此处的return,对应上文inner装饰器内的initialFunc(*args,**kwargs)
print(initialFunc(2, 3))
******************分割线*******************
#类实现的自带参数的高阶装饰器
import time
from functools import wraps
class Timeit:
def __init__(self, selfArgument):
self.selfArgument = selfArgument
def __call__(self, initialFunc):
@wraps(initialFunc)
def finalFunc(*args, **kwargs):
start = time.time()
initialResponse=initialFunc(*args, **kwargs) * 3
end = time.time()
print('%s运行了%d秒' % (self.selfArgument, int(end - start)))
return initialResponse
return finalFunc
@Timeit('自带参数的装饰器')
def initialFunc(s):
time.sleep(1.5)
print(s)
return s
result=initialFunc('hello,world!')
print(result)
****************************************分割线****************************************
#类的继承、多态
class Person:
def __init__(self, name, job=None, pay=0):
self.name = name
self.job = job
self.pay = pay
def __str__(self): # print函数
return 'personInfo:%s,%s' %(self.name, self.pay)
def salary(self, percent):
self.pay = int(self.pay * (1 + percent))
def lastName(self):
return self.name.split()[-1]
class Manager(Person):
def salary(self, percent, bonus=0.1):
Person.salary(self, percent + bonus) #继承
David = Person('David Alex')
Jack = Person('Jack Ma', 'Speaker', 5000)
Bill = Manager('Bill Gates', 'IT', 10000)
Jack.salary(0.2)
Bill.salary(0.3, 0.2)
[print(obj.lastName(), '…………', obj) for obj in (David, Jack, Bill)]
for obj in (David, Jack, Bill):
obj.salary(0.1) #多态:对象不同,则调用的salary版本不同
print(obj)
****************************************分割线****************************************
类继承中的super:
1、super多重继承的构造及实例函数,同普通多继承:广度优先,懒惰模式,即在匹配到第一个长辈类后就终止。
2、但是若首个长辈类也有super,就是贪婪模式了:公共爷类(如class E继承了B、C、D,而B、C、D又都继承了A),仅执行一次;各父类的super前的代码是广度顺序,之后的代码是广度逆序。
class A:
def __init__(self):
print("Enter A")
print("Leave A")
class B(A):
def __init__(self):
print("Enter B")
super(B, self).__init__()
print("Leave B")
class C(A):
def __init__(self):
print("Enter C")
super(C, self).__init__()
print("Leave C")
class D(A):
def __init__(self):
print("Enter D")
super(D, self).__init__() #此句取注或注释后,各运行一次,观察两次结果的区别
print("Leave D")
class E(B, C, D):
def __init__(self):
print("Enter E")
super(E, self).__init__()
print("Leave E")
E()
****************************************分割线****************************************
type函数生成class:
def fn(self, name='world'):
print('Hello, %s!' % name)
print(self.move)
class Animal:
move='run'
#type的首参是类名,二参()内是各父类,三参{}内是各方法或类属性
Dog = type('Dog', (Animal,), {'hi':fn,'attr':'xxx'})
xh=Dog()
xh.hi()
print(xh.attr)
****************************************分割线****************************************
自定义异常:
class MyError(Exception):
def __init__(self, value):
self.value = value
def __repr__(self):
return self.value
try:
raise MyError(2**3)
except MyError as e:
print('My exception occurred, value:', e)