函数

函数:

内置函数(链接)
一.函数初始
默认参数的陷阱
默认参数若是可变的数据类型,他始终使用的是一个内存地址。

def func1(x,l1=[]):
    l1.append(x)
    return l1
ret = func1(1)
ret1 = func1(100)

return是函数结束的标志,函数内可以写多个return,但只执行一次
无return 返回None
只写return,后面不写其他内容,也会返回None
return 逗号分隔多个值 返回元组
返回多个值,用多个变量接收
a,b,c,d = ret_demo2()

形参即变量名,实参即变量值
函数即变量 函数的赋值 f = func
命名关键字参数:*后定义的参数,必须被传值(有默认值的除外),且必须按照关键字实参的形式传递
可以保证,传入的参数中一定包含某些关键字

def foo(位置形参,*args,默认参数,**kwargs):
    函数体
    return 返回值

动态参数
溢出的位置参数值以元祖形式赋给args ,溢出的关键字参数以字典的形式赋给kwargs

*args,**kwargs
函数定义时:*聚合  *args:实参里面所有的位置参数。
                   **kwargs:实参里面所有的关键字参数。
函数的调用时:* 打散。
形参的顺序:位置参数,*args,默认参数,**kwargs。

二.函数进阶

存放名字与值的关系’的空间起了一个名字-------命名空间。

全局名称空间。
临时名称空间。
内置名称空间。
全局作用域: 全局名称空间,内置名称空间。
局部作用域: 局部名称空间。
取值顺序:就近原则,从小到大。
加载顺序:加载的是名称空间。
global nonlocal
globals() locals() 以字典形式返回模块全部全局变量和局部变量

全局作用域:包含内置名称空间、全局名称空间
局部作用域:局部名称空间,只能在局部范围内生效
  • 函数名的本质。

函数名本质上就是函数的内存地址。

  • 1.可以被引用

  • 2.可以被当作容器类型的元素

  • 3.可以当作函数的参数和返回值

第一类对象(first-class object)指
1.可在运行期创建
2.可用作函数参数或返回值
3.可存入变量的实体。

  • 一句话,函数名能当普通变量用

嵌套函数:
匿名函数:使用一次就释放

  • lambda x,y:x**y
  • 匿名函数主要是和其它函数搭配使用

高阶函数:
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
只需满足以下任意一个条件,即是高阶函数

  • 接受一个或多个函数作为输入
  • return 返回另外一个函数
def add(x,y,f):
    return f(x) + f(y)

递归
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

查看递归次数

n = 1
def func(x):
    print(x)
    x+=1
    func(x)
func(n)
def calc(n):
    v = int(n/2)
    print(v)
    if v > 0:
        calc(v)
    print(n)

calc(10)

递归特性:

  • 必须有一个明确的结束条件
  • 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
  • 递归效率不高,递归层次过多会导致栈溢出()
    应用:二分查找

闭包原理
闭包函数:内部函数包含对外部作用域而非全剧作用域变量的引用,该内部函数称为闭包函数,并返回.
闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
应用领域:延迟计算(原来我们是传参,现在我们是包起来)
闭包作用:
当程序执行时,遇到了函数执行,他会在内存中开辟一个空间,局部名称空间,
如果这个函数内部形成了闭包,
那么他就不会随着函数的结束而消失。

name = 'alex'
def wraaper():
    def inner():
        print(name)
    print(inner.__closure__)  # None不是闭包函数
    inner()
    return inner
wraaper()

name = 'hqs'
def wraaper(n):
    n = 'alex'
    def inner():
        print(n)
    print(inner.__closure__)  # cell at 0x000002AD93BF76D8 --> 是闭包函数
    inner()
    return inner
wraaper(name)

可迭代对象:Iterable
: str list dict,tuple,set,range()

对象内部含有iter方法就是可迭代对象.

print('__iter__' in dir(对象))  #返回True.False

from collections import Iterable #判断是否是可迭代对象
from collections import Iterator #判断是否是迭代器
print(isinstance('对象',Iterable))  # True/False
print(isinstance('对象',Iterator))  # True/False

可迭代对象满足可迭代协议。

迭代器:Iterator
对象内部含有__iter__方法且含有__next__方法就是迭代器.
文件本身就是迭代器对象

迭代器的缺点:

  • 取值麻烦,只能一个一个取,只能往后取,
  • 并且是一次性的,无法用len获取长度

可迭代对象不能取值,迭代器是可以取值的。
可迭代对象 --->(转化成)迭代器
迭代器=可迭代对象.iter() #等于 迭代器=iter(可迭代对象) #转化

1,将可迭代对象转化成迭代器。
2,调用next方法取值。
3,利用异常处理停止报错。

模式for循环

迭代器 = 可迭代对象.__iter__()
while 1:
    try:
        print(迭代器.__next__())
    except StopIteration:
        break

装饰器:

开放封闭原则:
软件上线后,对修改源代码是封闭的,对功能的扩展功能是开放的。
方案:装饰器

原则:
    * 1,不修改原代码
    * 2,不修改调用方式
目的:
    遵循1和2的基础上拓展新功能

装饰器:
装饰为被装饰对象添加新功能
含义:
装饰器即在不修改被装饰对象源代码与调用方式的前提下,为被装饰对象添加新功能

    装饰器 ==》函数
    被装饰的对象 ==》函数

    time.time() 获取当前时间(s)

生成器:就是自己python用代码写的迭代器,生成器的本质就是迭代器。
generator是可迭代对象 , 可用for循环和next()

用以下两种方式构建一个生成器:

  • 1,通过生成器函数。
  • 2,生成器表达式。

生成器函数 vs 迭代器:

  • 迭代器是需要可迭代对象进行转化。可迭代对象非常占内存。
  • 生成器直接创建,不需要转化,从本质就节省内存。
  • send 与next一样,也是对生成器取值(执行一个yield)的方法。
  • send 可以给上一个yield 传值。
  • 第一次取值永远都是next。
  • 最后一个yield 永远也得不到send传的值。
  • yield 将值返回给 生成器对象.next()

迭代器.next() 相当于 next(迭代器)

把函数做成迭代器
* 对比return,可以返回多次值,挂起函数的运行状态
创建生成器:如下

def func1():  #生成器函数
    print(1)
    count = (yield 6)
    print(count)
    count1 = (yield 7)
    print(count1)
    yield 8

g = func1()  #调用生成器函数创建生成器对象

print(next(g))
print(g.send('alex'))
print(g.send('alex'))
def cloth2(n):
    for i in range(1,n+1):
        yield '衣服%s号' % i
g = cloth2(10000)
for i in range(50):
    print(g.__next__())  #停在50的位置

for i in range(50):      #从51开始
    print(g.__next__())

列表推导式

  • 循环模式 : [变量(加工后的变量) for 变量 in iterable]
  • 筛选模式 : [变量(加工后的变量) for 变量 in iterable if 条件]
    优点:一行解决,方便。
    缺点:容易着迷,不易排错,不能超过三次循环。
    列表推导式不能解决所有列表的问题,所以不要太刻意用。

生成器表达式:
将列表推导式的 [] 换成() 即可。

三元表达式:ret = 'true' if 1 == 1 else 'false'

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355