【old】Python学习笔记

上学期看视频记得,也没学到多少,目前打算一边通过《Python学习手册 第四版》提高核心语法(太厚了 噗),一边学习Python Web开发

然后这里的多任务编程和网络编程是暑假学的

5. 函数

5.1 函数的参数

  ### 可变对象按引用传递,不可变对象按引用传递
# 避免对可变参数的修改:
L = [1,2]
change(L[:]) #
# 或
def change(l):
   l = l[:]

###【默认参数】【必须是不可变对象】
def power(x,n=2):
   return x**n
power(2) #=>4
power(2,3) #=>8

###【可变参数】(元祖)
def sum(*nums): #可以传入0到N个参数,函数内部接收到的是tuple
   s=0
   for x in nums:
       s+=x
   return s

###【关键字参数】(字典)
def preson(name,age,**kw): #可以传入0个或多个参数
print('name:',name,'age:',age,'other',kw)
person('bin',19,city='zz',job='stu') #=> name:bin age:19 other:{'city':'zz','job':'stu'}

###【元祖字典的】【拆包】
a=(1,2,3)
def func(*args):
   print(args)
func(a) # => ((1,2,3),) 没有*当作一个值,有*拆成N个值传入
func(*a) # => (1,2,3) 【拆包,拆成一个一个的值】 字典 传入 **a

 

5.2 函数式编程

5.2.1 匿名函数

  >>> func = lambda x : x*2 #分号前是参数,分号后是表达式,不用return,自动返回后面的值
>>> func(2) #=> 4
###【简单应用,字典排序,匿名函数作实参】
info = [{'name':'bin','age':19},{'name':'jin','age':19},{'son':'sname','age':1}]
info.sort(key=lambda x:x['name'])
print(info)

5.2.2 高阶函数

就是函数名可以作为参数使用

  ### map(func,seq) 将函数func作用于序列seq的每个元素,并返回一个迭代器
>>> list(map(lambda x:x*2,[1,2,3])) # => [2,4,6]

### reduce(func,seq) 把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
###reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
>>> from functools import reduce
>>> def fn(x, y):
...     return x * 10 + y
...
>>> reduce(fn, [1, 3, 5, 7, 9])
13579

###filter(func,seq) filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
def not_empty(s): #把列表的空字符串去掉
   return s and s.strip()

list(filter(not_empty, ['A', '', 'B', None, 'C', ' ']))
# 结果: ['A', 'B', 'C']

###sorted(seq,key=None,reverse=False)
>>> sorted([36, 5, -12, 9, -21])
[-21, -12, 5, 9, 36]
#还可以接收一个key函数来实现自定义的排序,key作用于每一个元素,并按作用后的seq排序
>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]

 

5.3 作用域

  a=1
def aa():
   global a  #如果没有global a的话,想要在函数中对a这个全局变量修改,仅仅a=0还不够,因为a是个与全局
   a=0  #变量相同的局部变量,需要用 global a将他声明为全局变量,然后修改
aa()
print(a) # => 0

##如果列表和字典当作全局变量时,可以不用global,直接在函数内部修改。因为列表字典是可变类型可以直接修改
l=[1,2,3]
def a():
   l.append(4)
a()
print(l) #=> [1,2,3,4]
###---------
a=100
def test(a):
   a+=a
   print(a) #=>200 没用global,函数外a不变
#-----------
a=[100]
def test(b): #b引用a指向的对象,如果对象是可变类型,下面可以修改全局变量,否则的话,重新指向复制的新的对象
   b+=b #=> 函数外:a => [100,100],
   b=b+b #=> [100]+[100]==>[100,100] 函数外:a => [100]。因为这里右侧新建了一个对象,b作为局部变量重新引用了一个新的对象。
   
   
#----对象名搜寻顺序----
#locals -> enclosing function -> globals -> builtins
#局部       闭包的外函数的局部变量   全局         内建

 

5.4 闭包

闭包就是内部函数引用了外部函数的临时变量,并且外部函数返回了内部函数的引用

  def outer(x):
   def wrapper(y):
       print(x+y)
   return wrapper
a = outer(1)#a现在是wrapper指向函数的引用
a(1)#2
a(2)#3

###【闭包无法修改外部函数的局部变量】
def outer():
   n = 1
   def wrapper():
       n -= 1 #error,
       n = 2 #相当于新定义了一个局部变量 n = 2
return wrapper

##通过nonlocal修改外部函数局部变量
def outer():
   n = 1 #将n定义为列表也可以,解决这个问题
   def wrapper():
       nonlocal n
       n -= 1
       print(n)
   return wrapper
a = outer()
a()#输出0
###闭包执行完成后,仍然能保持住当前的执行环境
a()#输出-1
a()#输出-2


###【注意事项】
# 当闭包内引用了一个后期会发生变化变量时
# 1.
def outer():
   a = 1
   def inner():
       print(a)
   a = 2
   return inner
a = outer()
a()#输出了2,因为inner后又修改了

## 2.
def outer():
   l = []
   for i in range(1,4):
       def inner():
           return i*i
       l.apend(inner)
   return l
f1,f2,f3 = outer()
print(f1(),f2(),f3())#9,9,9
#原因就在于返回的函数引用了变量i,但返回的函数并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9

#[解决:]
def outer():
   def f(j):
       def inner():
           return j*j
       return inner
   fs = []
   for i in range(1, 4):
       fs.append(f(i)) # f(i)立刻被执行(是一个数值,而不是函数),因此i的当前值被传入f()
   return fs

5.5 装饰器

就是不修改原函数的情况下,添加新的功能

  ###【装饰器原理】
def w1(func):
   def wrapper():
       print('这是新加功能')
       func()
   return wrapper

def f1():
   print('---f1---')

f1 = w1(f1)
f1() # 将会添加一个print



### 【使用@】
@w1 #在定义的函数面前使用 @包装函数。代码执行到这会立即执行函数w1。
def f2():
   print('---f2---')

f2() #将会添加一个print



###【添加多个装饰器】
def w1(func):
   def wrapper():
       print('w1')
       func()
   return wrapper

def w2(func):
   def wrapper():
       print('w2')
       func()
   return wrapper

@w2
@w1  #这样就添加了两个新功能;先w1装饰,然后w2再装饰,即w2装饰的是w1装饰的结果
def f():
   print('test...')

f()



###【带有参数的函数的装饰器】
def decorator(func):
   def wrapper(a,b):
       print('新功能')
       func(a,b)  #这里和wrapper添加参数
   return wrapper

@decorator
def sum(a,b):
   print('sum ',a+b)

sum(1,2)



###【不定长参数的装饰器】
def decorator(func):
   def wrapper(*args,**kwd): #这样就对没有参数、有n个参数,的函数都能使用了
       print('新功能')
       func(*args,**kwd)  #这里和wrapper添加参数
   return wrapper

@decorator
def sum(a,b):
   print('sum ',a+b)
   
@decorator
def sum2(a,b,c):
   print('sum ',a+b+c)
sum(1,2)
sum2(1,2,3)



###【装饰有返回值的函数】

转载于:https://www.cnblogs.com/yuanyb/p/9703875.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值